Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 71 additions & 14 deletions llvm/test/Transforms/LoopFusion/four_loops.ll
Original file line number Diff line number Diff line change
@@ -1,25 +1,82 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=loop-fusion < %s | FileCheck %s

@A = common global [1024 x i32] zeroinitializer, align 16
@B = common global [1024 x i32] zeroinitializer, align 16
@C = common global [1024 x i32] zeroinitializer, align 16
@D = common global [1024 x i32] zeroinitializer, align 16

; CHECK: void @dep_free
; CHECK-NEXT: bb:
; CHECK-NEXT: br label %[[LOOP1HEADER:bb[0-9]+]]
; CHECK: [[LOOP1HEADER]]
; CHECK: br label %[[LOOP2BODY:bb[0-9]+]]
; CHECK: [[LOOP2BODY]]
; CHECK: br label %[[LOOP3BODY:bb[0-9]+]]
; CHECK: [[LOOP3BODY]]
; CHECK: br label %[[LOOP4BODY:bb[0-9]+]]
; CHECK: [[LOOP4BODY]]
; CHECK: br label %[[LOOP1LATCH:bb[0-9]+]]
; CHECK: [[LOOP1LATCH]]
; CHECK: br i1 %{{.*}}, label %[[LOOP1HEADER]], label %[[LOOPEXIT:bb[0-9]+]]
; CHECK: ret void
define void @dep_free() {
; CHECK-LABEL: define void @dep_free() {
; CHECK-NEXT: [[BB:.*]]:
; CHECK-NEXT: br label %[[BB15:.*]]
; CHECK: [[BB15]]:
; CHECK-NEXT: [[DOT08:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[TMP23:%.*]], %[[BB61:.*]] ]
; CHECK-NEXT: [[INDVARS_IV107:%.*]] = phi i64 [ 0, %[[BB]] ], [ [[INDVARS_IV_NEXT11:%.*]], %[[BB61]] ]
; CHECK-NEXT: [[DOT016:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[TMP36:%.*]], %[[BB61]] ]
; CHECK-NEXT: [[INDVARS_IV75:%.*]] = phi i64 [ 0, %[[BB]] ], [ [[INDVARS_IV_NEXT8:%.*]], %[[BB61]] ]
; CHECK-NEXT: [[DOT024:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[TMP49:%.*]], %[[BB61]] ]
; CHECK-NEXT: [[INDVARS_IV43:%.*]] = phi i64 [ 0, %[[BB]] ], [ [[INDVARS_IV_NEXT5:%.*]], %[[BB61]] ]
; CHECK-NEXT: [[DOT032:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[TMP62:%.*]], %[[BB61]] ]
; CHECK-NEXT: [[INDVARS_IV1:%.*]] = phi i64 [ 0, %[[BB]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[BB61]] ]
; CHECK-NEXT: [[TMP:%.*]] = add nsw i32 [[DOT08]], -3
; CHECK-NEXT: [[TMP16:%.*]] = add nuw nsw i64 [[INDVARS_IV107]], 3
; CHECK-NEXT: [[TMP17:%.*]] = trunc i64 [[TMP16]] to i32
; CHECK-NEXT: [[TMP18:%.*]] = mul nsw i32 [[TMP]], [[TMP17]]
; CHECK-NEXT: [[TMP19:%.*]] = trunc i64 [[INDVARS_IV107]] to i32
; CHECK-NEXT: [[TMP20:%.*]] = srem i32 [[TMP18]], [[TMP19]]
; CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1024 x i32], ptr @A, i64 0, i64 [[INDVARS_IV107]]
; CHECK-NEXT: store i32 [[TMP20]], ptr [[TMP21]], align 4
; CHECK-NEXT: br label %[[BB22:.*]]
; CHECK: [[BB22]]:
; CHECK-NEXT: [[TMP28:%.*]] = add nsw i32 [[DOT016]], -3
; CHECK-NEXT: [[TMP29:%.*]] = add nuw nsw i64 [[INDVARS_IV75]], 3
; CHECK-NEXT: [[TMP30:%.*]] = trunc i64 [[TMP29]] to i32
; CHECK-NEXT: [[TMP31:%.*]] = mul nsw i32 [[TMP28]], [[TMP30]]
; CHECK-NEXT: [[TMP32:%.*]] = trunc i64 [[INDVARS_IV75]] to i32
; CHECK-NEXT: [[TMP33:%.*]] = srem i32 [[TMP31]], [[TMP32]]
; CHECK-NEXT: [[TMP34:%.*]] = getelementptr inbounds [1024 x i32], ptr @B, i64 0, i64 [[INDVARS_IV75]]
; CHECK-NEXT: store i32 [[TMP33]], ptr [[TMP34]], align 4
; CHECK-NEXT: br label %[[BB35:.*]]
; CHECK: [[BB35]]:
; CHECK-NEXT: [[TMP41:%.*]] = add nsw i32 [[DOT024]], -3
; CHECK-NEXT: [[TMP42:%.*]] = add nuw nsw i64 [[INDVARS_IV43]], 3
; CHECK-NEXT: [[TMP43:%.*]] = trunc i64 [[TMP42]] to i32
; CHECK-NEXT: [[TMP44:%.*]] = mul nsw i32 [[TMP41]], [[TMP43]]
; CHECK-NEXT: [[TMP45:%.*]] = trunc i64 [[INDVARS_IV43]] to i32
; CHECK-NEXT: [[TMP46:%.*]] = srem i32 [[TMP44]], [[TMP45]]
; CHECK-NEXT: [[TMP47:%.*]] = getelementptr inbounds [1024 x i32], ptr @C, i64 0, i64 [[INDVARS_IV43]]
; CHECK-NEXT: store i32 [[TMP46]], ptr [[TMP47]], align 4
; CHECK-NEXT: br label %[[BB48:.*]]
; CHECK: [[BB48]]:
; CHECK-NEXT: [[TMP54:%.*]] = add nsw i32 [[DOT032]], -3
; CHECK-NEXT: [[TMP55:%.*]] = add nuw nsw i64 [[INDVARS_IV1]], 3
; CHECK-NEXT: [[TMP56:%.*]] = trunc i64 [[TMP55]] to i32
; CHECK-NEXT: [[TMP57:%.*]] = mul nsw i32 [[TMP54]], [[TMP56]]
; CHECK-NEXT: [[TMP58:%.*]] = trunc i64 [[INDVARS_IV1]] to i32
; CHECK-NEXT: [[TMP59:%.*]] = srem i32 [[TMP57]], [[TMP58]]
; CHECK-NEXT: [[TMP60:%.*]] = getelementptr inbounds [1024 x i32], ptr @D, i64 0, i64 [[INDVARS_IV1]]
; CHECK-NEXT: store i32 [[TMP59]], ptr [[TMP60]], align 4
; CHECK-NEXT: br label %[[BB61]]
; CHECK: [[BB52:.*]]:
; CHECK-NEXT: br label %[[BB63:.*]]
; CHECK: [[BB61]]:
; CHECK-NEXT: [[INDVARS_IV_NEXT11]] = add nuw nsw i64 [[INDVARS_IV107]], 1
; CHECK-NEXT: [[TMP23]] = add nuw nsw i32 [[DOT08]], 1
; CHECK-NEXT: [[EXITCOND12:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT11]], 100
; CHECK-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV75]], 1
; CHECK-NEXT: [[TMP36]] = add nuw nsw i32 [[DOT016]], 1
; CHECK-NEXT: [[EXITCOND9:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT8]], 100
; CHECK-NEXT: [[INDVARS_IV_NEXT5]] = add nuw nsw i64 [[INDVARS_IV43]], 1
; CHECK-NEXT: [[TMP49]] = add nuw nsw i32 [[DOT024]], 1
; CHECK-NEXT: [[EXITCOND6:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT5]], 100
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV1]], 1
; CHECK-NEXT: [[TMP62]] = add nuw nsw i32 [[DOT032]], 1
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 100
; CHECK-NEXT: br i1 [[EXITCOND]], label %[[BB15]], label %[[BB52]]
; CHECK: [[BB63]]:
; CHECK-NEXT: ret void
;
bb:
br label %bb15

Expand Down
93 changes: 68 additions & 25 deletions llvm/test/Transforms/LoopFusion/guarded_peel.ll
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=loop-fusion -loop-fusion-peel-max-count=3 < %s | FileCheck %s

; Tests if we are able to fuse two guarded loops which have constant but
Expand All @@ -6,33 +7,75 @@

@B = common global [1024 x i32] zeroinitializer, align 16

; CHECK-LABEL: void @main(ptr noalias %A)
; CHECK-NEXT: entry:
; CHECK: br i1 %cmp4, label %for.first.entry, label %for.end
; CHECK: for.first.entry
; CHECK-NEXT: br label %for.first.peel.begin
; CHECK: for.first.peel.begin:
; CHECK-NEXT: br label %for.first.peel
; CHECK: for.first.peel:
; CHECK: br label %for.first.peel.next
; CHECK: for.first.peel.next:
; CHECK-NEXT: br label %for.first.peel2
; CHECK: for.first.peel2:
; CHECK: br label %for.first.peel.next1
; CHECK: for.first.peel.next1:
; CHECK-NEXT: br label %for.first.peel.next11
; CHECK: for.first.peel.next11:
; CHECK-NEXT: br label %for.first.entry.peel.newph
; CHECK: for.first.entry.peel.newph:
; CHECK: br label %for.first
; CHECK: for.first:
; CHECK: br i1 %cmp3, label %for.first, label %for.second.exit
; CHECK: for.second.exit:
; CHECK: br label %for.end
; CHECK: for.end:
; CHECK-NEXT: ret void

define void @main(ptr noalias %A) {
; CHECK-LABEL: define void @main(
; CHECK-SAME: ptr noalias [[A:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[CMP4:%.*]] = icmp slt i64 0, 45
; CHECK-NEXT: [[CMP31:%.*]] = icmp slt i64 2, 45
; CHECK-NEXT: br i1 [[CMP4]], label %[[FOR_FIRST_ENTRY:.*]], label %[[FOR_END:.*]]
; CHECK: [[FOR_FIRST_ENTRY]]:
; CHECK-NEXT: br label %[[FOR_FIRST_PEEL_BEGIN:.*]]
; CHECK: [[FOR_FIRST_PEEL_BEGIN]]:
; CHECK-NEXT: br label %[[FOR_FIRST_PEEL:.*]]
; CHECK: [[FOR_FIRST_PEEL]]:
; CHECK-NEXT: [[SUB_PEEL:%.*]] = sub nsw i64 0, 3
; CHECK-NEXT: [[ADD_PEEL:%.*]] = add nsw i64 0, 3
; CHECK-NEXT: [[MUL_PEEL:%.*]] = mul nsw i64 [[SUB_PEEL]], [[ADD_PEEL]]
; CHECK-NEXT: [[REM_PEEL:%.*]] = srem i64 [[MUL_PEEL]], 0
; CHECK-NEXT: [[CONV_PEEL:%.*]] = trunc i64 [[REM_PEEL]] to i32
; CHECK-NEXT: [[ARRAYIDX_PEEL:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 0
; CHECK-NEXT: store i32 [[CONV_PEEL]], ptr [[ARRAYIDX_PEEL]], align 4
; CHECK-NEXT: [[INC_PEEL:%.*]] = add nsw i64 0, 1
; CHECK-NEXT: [[CMP_PEEL:%.*]] = icmp slt i64 [[INC_PEEL]], 45
; CHECK-NEXT: br label %[[FOR_FIRST_PEEL_NEXT:.*]]
; CHECK: [[FOR_FIRST_PEEL_NEXT]]:
; CHECK-NEXT: br label %[[FOR_FIRST_PEEL2:.*]]
; CHECK: [[FOR_FIRST_PEEL2]]:
; CHECK-NEXT: [[SUB_PEEL3:%.*]] = sub nsw i64 [[INC_PEEL]], 3
; CHECK-NEXT: [[ADD_PEEL4:%.*]] = add nsw i64 [[INC_PEEL]], 3
; CHECK-NEXT: [[MUL_PEEL5:%.*]] = mul nsw i64 [[SUB_PEEL3]], [[ADD_PEEL4]]
; CHECK-NEXT: [[REM_PEEL6:%.*]] = srem i64 [[MUL_PEEL5]], [[INC_PEEL]]
; CHECK-NEXT: [[CONV_PEEL7:%.*]] = trunc i64 [[REM_PEEL6]] to i32
; CHECK-NEXT: [[ARRAYIDX_PEEL8:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INC_PEEL]]
; CHECK-NEXT: store i32 [[CONV_PEEL7]], ptr [[ARRAYIDX_PEEL8]], align 4
; CHECK-NEXT: [[INC_PEEL9:%.*]] = add nsw i64 [[INC_PEEL]], 1
; CHECK-NEXT: [[CMP_PEEL10:%.*]] = icmp slt i64 [[INC_PEEL9]], 45
; CHECK-NEXT: br label %[[FOR_FIRST_PEEL_NEXT1:.*]]
; CHECK: [[FOR_FIRST_PEEL_NEXT1]]:
; CHECK-NEXT: br label %[[FOR_FIRST_PEEL_NEXT11:.*]]
; CHECK: [[FOR_FIRST_PEEL_NEXT11]]:
; CHECK-NEXT: br label %[[FOR_FIRST_ENTRY_PEEL_NEWPH:.*]]
; CHECK: [[FOR_FIRST_ENTRY_PEEL_NEWPH]]:
; CHECK-NEXT: br label %[[FOR_FIRST:.*]]
; CHECK: [[FOR_FIRST]]:
; CHECK-NEXT: [[I_05:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_FIRST]] ], [ [[INC_PEEL9]], %[[FOR_FIRST_ENTRY_PEEL_NEWPH]] ]
; CHECK-NEXT: [[I1_02:%.*]] = phi i64 [ [[INC14:%.*]], %[[FOR_FIRST]] ], [ 2, %[[FOR_FIRST_ENTRY_PEEL_NEWPH]] ]
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i64 [[I_05]], 3
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[I_05]], 3
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i64 [[SUB]], [[ADD]]
; CHECK-NEXT: [[REM:%.*]] = srem i64 [[MUL]], [[I_05]]
; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[REM]] to i32
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[I_05]]
; CHECK-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4
; CHECK-NEXT: [[INC]] = add nsw i64 [[I_05]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INC]], 45
; CHECK-NEXT: [[SUB7:%.*]] = sub nsw i64 [[I1_02]], 3
; CHECK-NEXT: [[ADD8:%.*]] = add nsw i64 [[I1_02]], 3
; CHECK-NEXT: [[MUL9:%.*]] = mul nsw i64 [[SUB7]], [[ADD8]]
; CHECK-NEXT: [[REM10:%.*]] = srem i64 [[MUL9]], [[I1_02]]
; CHECK-NEXT: [[CONV11:%.*]] = trunc i64 [[REM10]] to i32
; CHECK-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [1024 x i32], ptr @B, i64 0, i64 [[I1_02]]
; CHECK-NEXT: store i32 [[CONV11]], ptr [[ARRAYIDX12]], align 4
; CHECK-NEXT: [[INC14]] = add nsw i64 [[I1_02]], 1
; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i64 [[INC14]], 45
; CHECK-NEXT: br i1 [[CMP3]], label %[[FOR_FIRST]], label %[[FOR_SECOND_EXIT:.*]]
; CHECK: [[FOR_SECOND_EXIT]]:
; CHECK-NEXT: br label %[[FOR_END]]
; CHECK: [[FOR_END]]:
; CHECK-NEXT: ret void
;
entry:
%cmp4 = icmp slt i64 0, 45
br i1 %cmp4, label %for.first.entry, label %for.second.guard
Expand Down
55 changes: 35 additions & 20 deletions llvm/test/Transforms/LoopFusion/guarded_unsafeblock_peel.ll
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=loop-fusion -loop-fusion-peel-max-count=3 < %s | FileCheck %s

; Tests that we do not fuse two guarded loops together.
Expand All @@ -6,28 +7,42 @@
; loops unsafe to fuse together.
; The expected output of this test is the function as below.

; CHECK-LABEL: void @unsafe_exitblock(ptr noalias %A, ptr noalias %B)
; CHECK: for.first.guard
; CHECK: br i1 %cmp3, label %for.first.preheader, label %for.second.guard
; CHECK: for.first.preheader:
; CHECK-NEXT: br label %for.first
; CHECK: for.first:
; CHECK: br i1 %cmp, label %for.first, label %for.first.exit
; CHECK: for.first.exit:
; CHECK-NEXT: call void @bar()
; CHECK-NEXT: br label %for.second.guard
; CHECK: for.second.guard:
; CHECK: br i1 %cmp21, label %for.second.preheader, label %for.end
; CHECK: for.second.preheader:
; CHECK-NEXT: br label %for.second
; CHECK: for.second:
; CHECK: br i1 %cmp2, label %for.second, label %for.second.exit
; CHECK: for.second.exit:
; CHECK-NEXT: br label %for.end
; CHECK: for.end:
; CHECK-NEXT: ret void

define void @unsafe_exitblock(ptr noalias %A, ptr noalias %B) {
; CHECK-LABEL: define void @unsafe_exitblock(
; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
; CHECK-NEXT: [[FOR_FIRST_GUARD:.*:]]
; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i64 0, 45
; CHECK-NEXT: br i1 [[CMP3]], label %[[FOR_FIRST_PREHEADER:.*]], label %[[FOR_SECOND_GUARD:.*]]
; CHECK: [[FOR_FIRST_PREHEADER]]:
; CHECK-NEXT: br label %[[FOR_FIRST:.*]]
; CHECK: [[FOR_FIRST]]:
; CHECK-NEXT: [[I_04:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_FIRST]] ], [ 0, %[[FOR_FIRST_PREHEADER]] ]
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[I_04]]
; CHECK-NEXT: store i32 0, ptr [[ARRAYIDX]], align 4
; CHECK-NEXT: [[INC]] = add nsw i64 [[I_04]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[INC]], 45
; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_FIRST]], label %[[FOR_FIRST_EXIT:.*]]
; CHECK: [[FOR_FIRST_EXIT]]:
; CHECK-NEXT: call void @bar()
; CHECK-NEXT: br label %[[FOR_SECOND_GUARD]]
; CHECK: [[FOR_SECOND_GUARD]]:
; CHECK-NEXT: [[CMP21:%.*]] = icmp slt i64 2, 45
; CHECK-NEXT: br i1 [[CMP21]], label %[[FOR_SECOND_PREHEADER:.*]], label %[[FOR_END:.*]]
; CHECK: [[FOR_SECOND_PREHEADER]]:
; CHECK-NEXT: br label %[[FOR_SECOND:.*]]
; CHECK: [[FOR_SECOND]]:
; CHECK-NEXT: [[J_02:%.*]] = phi i64 [ [[INC6:%.*]], %[[FOR_SECOND]] ], [ 2, %[[FOR_SECOND_PREHEADER]] ]
; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[J_02]]
; CHECK-NEXT: store i32 0, ptr [[ARRAYIDX4]], align 4
; CHECK-NEXT: [[INC6]] = add nsw i64 [[J_02]], 1
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[INC6]], 45
; CHECK-NEXT: br i1 [[CMP2]], label %[[FOR_SECOND]], label %[[FOR_SECOND_EXIT:.*]]
; CHECK: [[FOR_SECOND_EXIT]]:
; CHECK-NEXT: br label %[[FOR_END]]
; CHECK: [[FOR_END]]:
; CHECK-NEXT: ret void
;
for.first.guard:
%cmp3 = icmp slt i64 0, 45
br i1 %cmp3, label %for.first.preheader, label %for.second.guard
Expand Down
25 changes: 18 additions & 7 deletions llvm/test/Transforms/LoopFusion/hoist_preheader.ll
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=loop-fusion < %s | FileCheck %s

define void @hoist_preheader(i32 %N) {

; CHECK:pre1:
; CHECK-NEXT: %hoistme = add i32 1, %N
; CHECK-NEXT: %hoistme2 = add i32 1, %hoistme
; CHECK-NEXT: br label %body1
; CHECK-LABEL: define void @hoist_preheader(
; CHECK-SAME: i32 [[N:%.*]]) {
; CHECK-NEXT: [[PRE1:.*]]:
; CHECK-NEXT: [[HOISTME:%.*]] = add i32 1, [[N]]
; CHECK-NEXT: [[HOISTME2:%.*]] = add i32 1, [[HOISTME]]
; CHECK-NEXT: br label %[[BODY1:.*]]
; CHECK: [[BODY1]]:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], %[[BODY1]] ], [ 0, %[[PRE1]] ]
; CHECK-NEXT: [[I2:%.*]] = phi i32 [ [[I_NEXT2:%.*]], %[[BODY1]] ], [ 0, %[[PRE1]] ]
; CHECK-NEXT: [[I_NEXT]] = add i32 1, [[I]]
; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[I]], [[N]]
; CHECK-NEXT: [[I_NEXT2]] = add i32 1, [[I2]]
; CHECK-NEXT: [[COND2:%.*]] = icmp ne i32 [[I2]], [[N]]
; CHECK-NEXT: br i1 [[COND2]], label %[[BODY1]], label %[[EXIT:.*]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
pre1:
br label %body1

; CHECK: body1:
; CHECK-NOT: %hoistme
body1: ; preds = %pre1, %body1
%i = phi i32 [%i_next, %body1], [0, %pre1]
%i_next = add i32 1, %i
Expand Down
72 changes: 56 additions & 16 deletions llvm/test/Transforms/LoopFusion/inner_loops.ll
Original file line number Diff line number Diff line change
@@ -1,26 +1,66 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=loop-fusion < %s 2>&1 | FileCheck %s

@A = common global [1024 x [1024 x i32]] zeroinitializer, align 16
@B = common global [1024 x [1024 x i32]] zeroinitializer, align 16

; CHECK: void @dep_free
; CHECK-NEXT: bb:
; CHECK-NEXT: br label %[[LOOP1HEADER:bb[0-9]*]]
; CHECK: [[LOOP1HEADER]]
; CHECK: br i1 %{{.*}}, label %[[LOOP1BODY:bb[0-9]*]], label %[[LOOP2PREHEADER:bb[0-9]+]]
; CHECK: [[LOOP1BODY]]
; CHECK: br label %[[LOOP1LATCH:bb[0-9]*]]
; CHECK: [[LOOP1LATCH]]
; CHECK: br label %[[LOOP2PREHEADER:bb[0-9]+]]
; CHECK: [[LOOP2PREHEADER]]
; CHECK: br i1 %{{.*}}, label %[[LOOP2BODY:bb[0-9]*]], label %[[LOOP2EXIT:bb[0-9]*]]
; CHECK: [[LOOP2BODY]]
; CHECK: br label %[[LOOP2LATCH:bb[0-9]+]]
; CHECK: [[LOOP2LATCH]]
; CHECK: br label %[[LOOP1HEADER]]
; CHECK: ret void

define void @dep_free() {
; CHECK-LABEL: define void @dep_free() {
; CHECK-NEXT: [[BB:.*]]:
; CHECK-NEXT: br label %[[BB9:.*]]
; CHECK: [[BB9]]:
; CHECK-NEXT: [[INDVARS_IV6:%.*]] = phi i64 [ [[INDVARS_IV_NEXT7:%.*]], %[[BB35:.*]] ], [ 0, %[[BB]] ]
; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[TMP36:%.*]], %[[BB35]] ]
; CHECK-NEXT: [[EXITCOND8:%.*]] = icmp ne i64 [[INDVARS_IV6]], 100
; CHECK-NEXT: br i1 [[EXITCOND8]], label %[[BB11:.*]], label %[[BB10:.*]]
; CHECK: [[BB10]]:
; CHECK-NEXT: br label %[[BB37:.*]]
; CHECK: [[BB11]]:
; CHECK-NEXT: br label %[[BB12:.*]]
; CHECK: [[BB12]]:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[BB21:.*]] ], [ 0, %[[BB11]] ]
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], 100
; CHECK-NEXT: br i1 [[EXITCOND]], label %[[BB14:.*]], label %[[BB23_PREHEADER:.*]]
; CHECK: [[BB23_PREHEADER]]:
; CHECK-NEXT: br label %[[BB23:.*]]
; CHECK: [[BB14]]:
; CHECK-NEXT: [[TMP:%.*]] = add nsw i32 [[DOT0]], -3
; CHECK-NEXT: [[TMP15:%.*]] = add nuw nsw i64 [[INDVARS_IV6]], 3
; CHECK-NEXT: [[TMP16:%.*]] = trunc i64 [[TMP15]] to i32
; CHECK-NEXT: [[TMP17:%.*]] = mul nsw i32 [[TMP]], [[TMP16]]
; CHECK-NEXT: [[TMP18:%.*]] = trunc i64 [[INDVARS_IV6]] to i32
; CHECK-NEXT: [[TMP19:%.*]] = srem i32 [[TMP17]], [[TMP18]]
; CHECK-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1024 x [1024 x i32]], ptr @A, i64 0, i64 [[INDVARS_IV6]], i64 [[INDVARS_IV]]
; CHECK-NEXT: store i32 [[TMP19]], ptr [[TMP20]], align 4
; CHECK-NEXT: br label %[[BB21]]
; CHECK: [[BB21]]:
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
; CHECK-NEXT: br label %[[BB12]]
; CHECK: [[BB23]]:
; CHECK-NEXT: [[INDVARS_IV3:%.*]] = phi i64 [ [[INDVARS_IV_NEXT4:%.*]], %[[BB33:.*]] ], [ 0, %[[BB23_PREHEADER]] ]
; CHECK-NEXT: [[EXITCOND5:%.*]] = icmp ne i64 [[INDVARS_IV3]], 100
; CHECK-NEXT: br i1 [[EXITCOND5]], label %[[BB25:.*]], label %[[BB35]]
; CHECK: [[BB25]]:
; CHECK-NEXT: [[TMP26:%.*]] = add nsw i32 [[DOT0]], -3
; CHECK-NEXT: [[TMP27:%.*]] = add nuw nsw i64 [[INDVARS_IV6]], 3
; CHECK-NEXT: [[TMP28:%.*]] = trunc i64 [[TMP27]] to i32
; CHECK-NEXT: [[TMP29:%.*]] = mul nsw i32 [[TMP26]], [[TMP28]]
; CHECK-NEXT: [[TMP30:%.*]] = trunc i64 [[INDVARS_IV6]] to i32
; CHECK-NEXT: [[TMP31:%.*]] = srem i32 [[TMP29]], [[TMP30]]
; CHECK-NEXT: [[TMP32:%.*]] = getelementptr inbounds [1024 x [1024 x i32]], ptr @B, i64 0, i64 [[INDVARS_IV6]], i64 [[INDVARS_IV3]]
; CHECK-NEXT: store i32 [[TMP31]], ptr [[TMP32]], align 4
; CHECK-NEXT: br label %[[BB33]]
; CHECK: [[BB33]]:
; CHECK-NEXT: [[INDVARS_IV_NEXT4]] = add nuw nsw i64 [[INDVARS_IV3]], 1
; CHECK-NEXT: br label %[[BB23]]
; CHECK: [[BB35]]:
; CHECK-NEXT: [[INDVARS_IV_NEXT7]] = add nuw nsw i64 [[INDVARS_IV6]], 1
; CHECK-NEXT: [[TMP36]] = add nuw nsw i32 [[DOT0]], 1
; CHECK-NEXT: br label %[[BB9]]
; CHECK: [[BB37]]:
; CHECK-NEXT: ret void
;
bb:
br label %bb9

Expand Down
Loading