xref: /llvm-project/llvm/test/Transforms/LoopUnroll/shifted-tripcount.ll (revision 175d2971020ceaad3e1adcf9bb92e4ebaaa449ee)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=loop-unroll -unroll-count=2 -S | FileCheck %s
3
4; LoopUnroll should unroll this loop into one big basic block.
5define void @latch_exit(ptr nocapture %p, i64 %n) nounwind {
6; CHECK-LABEL: @latch_exit(
7; CHECK-NEXT:  entry:
8; CHECK-NEXT:    [[MUL10:%.*]] = shl i64 [[N:%.*]], 1
9; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
10; CHECK:       for.body:
11; CHECK-NEXT:    [[I_013:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[TMP16_1:%.*]], [[FOR_BODY]] ]
12; CHECK-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr double, ptr [[P:%.*]], i64 [[I_013]]
13; CHECK-NEXT:    [[TMP16:%.*]] = add nuw nsw i64 [[I_013]], 1
14; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr double, ptr [[P]], i64 [[TMP16]]
15; CHECK-NEXT:    [[TMP4:%.*]] = load double, ptr [[ARRAYIDX]], align 8
16; CHECK-NEXT:    [[TMP8:%.*]] = load double, ptr [[ARRAYIDX7]], align 8
17; CHECK-NEXT:    [[MUL9:%.*]] = fmul double [[TMP8]], [[TMP4]]
18; CHECK-NEXT:    store double [[MUL9]], ptr [[ARRAYIDX7]], align 8
19; CHECK-NEXT:    [[ARRAYIDX7_1:%.*]] = getelementptr double, ptr [[P]], i64 [[TMP16]]
20; CHECK-NEXT:    [[TMP16_1]] = add i64 [[I_013]], 2
21; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr double, ptr [[P]], i64 [[TMP16_1]]
22; CHECK-NEXT:    [[TMP4_1:%.*]] = load double, ptr [[ARRAYIDX_1]], align 8
23; CHECK-NEXT:    [[MUL9_1:%.*]] = fmul double [[TMP4]], [[TMP4_1]]
24; CHECK-NEXT:    store double [[MUL9_1]], ptr [[ARRAYIDX7_1]], align 8
25; CHECK-NEXT:    [[EXITCOND_1:%.*]] = icmp eq i64 [[TMP16_1]], [[MUL10]]
26; CHECK-NEXT:    br i1 [[EXITCOND_1]], label [[FOR_END:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
27; CHECK:       for.end:
28; CHECK-NEXT:    ret void
29;
30entry:
31  %mul10 = shl i64 %n, 1
32  br label %for.body
33
34for.body:
35  %i.013 = phi i64 [ %tmp16, %for.body ], [ 0, %entry ]
36  %arrayidx7 = getelementptr double, ptr %p, i64 %i.013
37  %tmp16 = add i64 %i.013, 1
38  %arrayidx = getelementptr double, ptr %p, i64 %tmp16
39  %tmp4 = load double, ptr %arrayidx
40  %tmp8 = load double, ptr %arrayidx7
41  %mul9 = fmul double %tmp8, %tmp4
42  store double %mul9, ptr %arrayidx7
43  %exitcond = icmp eq i64 %tmp16, %mul10
44  br i1 %exitcond, label %for.end, label %for.body
45
46for.end:
47  ret void
48}
49
50; Same as previous test case, but with a non-latch exit. There shouldn't
51; be a conditional branch after the first block.
52define void @non_latch_exit(ptr nocapture %p, i64 %n) nounwind {
53; CHECK-LABEL: @non_latch_exit(
54; CHECK-NEXT:  entry:
55; CHECK-NEXT:    [[MUL10:%.*]] = shl i64 [[N:%.*]], 1
56; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
57; CHECK:       for.body:
58; CHECK-NEXT:    [[I_013:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[TMP16_1:%.*]], [[LATCH_1:%.*]] ]
59; CHECK-NEXT:    [[ARRAYIDX7:%.*]] = getelementptr double, ptr [[P:%.*]], i64 [[I_013]]
60; CHECK-NEXT:    [[TMP16:%.*]] = add nuw nsw i64 [[I_013]], 1
61; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr double, ptr [[P]], i64 [[TMP16]]
62; CHECK-NEXT:    [[TMP4:%.*]] = load double, ptr [[ARRAYIDX]], align 8
63; CHECK-NEXT:    [[TMP8:%.*]] = load double, ptr [[ARRAYIDX7]], align 8
64; CHECK-NEXT:    [[MUL9:%.*]] = fmul double [[TMP8]], [[TMP4]]
65; CHECK-NEXT:    store double [[MUL9]], ptr [[ARRAYIDX7]], align 8
66; CHECK-NEXT:    br label [[LATCH:%.*]]
67; CHECK:       latch:
68; CHECK-NEXT:    [[ARRAYIDX7_1:%.*]] = getelementptr double, ptr [[P]], i64 [[TMP16]]
69; CHECK-NEXT:    [[TMP16_1]] = add i64 [[I_013]], 2
70; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr double, ptr [[P]], i64 [[TMP16_1]]
71; CHECK-NEXT:    [[TMP4_1:%.*]] = load double, ptr [[ARRAYIDX_1]], align 8
72; CHECK-NEXT:    [[MUL9_1:%.*]] = fmul double [[TMP4]], [[TMP4_1]]
73; CHECK-NEXT:    store double [[MUL9_1]], ptr [[ARRAYIDX7_1]], align 8
74; CHECK-NEXT:    [[EXITCOND_1:%.*]] = icmp eq i64 [[TMP16_1]], [[MUL10]]
75; CHECK-NEXT:    br i1 [[EXITCOND_1]], label [[FOR_END:%.*]], label [[LATCH_1]]
76; CHECK:       latch.1:
77; CHECK-NEXT:    br label [[FOR_BODY]], !llvm.loop [[LOOP2:![0-9]+]]
78; CHECK:       for.end:
79; CHECK-NEXT:    ret void
80;
81entry:
82  %mul10 = shl i64 %n, 1
83  br label %for.body
84
85for.body:
86  %i.013 = phi i64 [ %tmp16, %latch ], [ 0, %entry ]
87  %arrayidx7 = getelementptr double, ptr %p, i64 %i.013
88  %tmp16 = add i64 %i.013, 1
89  %arrayidx = getelementptr double, ptr %p, i64 %tmp16
90  %tmp4 = load double, ptr %arrayidx
91  %tmp8 = load double, ptr %arrayidx7
92  %mul9 = fmul double %tmp8, %tmp4
93  store double %mul9, ptr %arrayidx7
94  %exitcond = icmp eq i64 %tmp16, %mul10
95  br i1 %exitcond, label %for.end, label %latch
96
97latch:
98  br label %for.body
99
100for.end:
101  ret void
102}
103