150
|
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
2 ; RUN: opt < %s -S -loop-unroll -unroll-allow-partial | FileCheck %s
|
|
3
|
|
4 ; The phi which acts as input to func should not be undef. It should
|
|
5 ; have its loop-carried value (the load in for.cond) replaced accordingly
|
|
6 ; after unrolling the loop.
|
|
7
|
|
8 define i16 @full_unroll(i16* %A) {
|
|
9 ; CHECK-LABEL: @full_unroll(
|
|
10 ; CHECK-NEXT: entry:
|
|
11 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
|
12 ; CHECK: for.cond:
|
173
|
13 ; CHECK-NEXT: [[TMP2:%.*]] = load i16, i16* [[A:%.*]], align 2
|
150
|
14 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP3:%.*]]
|
|
15 ; CHECK: for.cond.cleanup:
|
|
16 ; CHECK-NEXT: [[DOTLCSSA10_LCSSA:%.*]] = phi i16 [ [[TMP2_2:%.*]], [[FOR_COND_CLEANUP3_2:%.*]] ]
|
|
17 ; CHECK-NEXT: [[TMP3:%.*]] = call i16 @func(i16 [[DOTLCSSA10_LCSSA]])
|
|
18 ; CHECK-NEXT: ret i16 0
|
|
19 ; CHECK: for.cond.cleanup3:
|
|
20 ; CHECK-NEXT: [[PTR_1:%.*]] = getelementptr inbounds i16, i16* [[A]], i64 1
|
173
|
21 ; CHECK-NEXT: [[TMP2_1:%.*]] = load i16, i16* [[PTR_1]], align 2
|
150
|
22 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP3_1:%.*]]
|
|
23 ; CHECK: for.cond.cleanup3.1:
|
|
24 ; CHECK-NEXT: [[PTR_2:%.*]] = getelementptr inbounds i16, i16* [[A]], i64 2
|
173
|
25 ; CHECK-NEXT: [[TMP2_2]] = load i16, i16* [[PTR_2]], align 2
|
150
|
26 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP3_2]]
|
|
27 ; CHECK: for.cond.cleanup3.2:
|
|
28 ; CHECK-NEXT: [[PTR_3:%.*]] = getelementptr inbounds i16, i16* [[A]], i64 3
|
173
|
29 ; CHECK-NEXT: [[TMP2_3:%.*]] = load i16, i16* [[PTR_3]], align 2
|
150
|
30 ; CHECK-NEXT: br i1 false, label [[FOR_COND_CLEANUP3_3:%.*]], label [[FOR_COND_CLEANUP:%.*]]
|
|
31 ; CHECK: for.cond.cleanup3.3:
|
|
32 ; CHECK-NEXT: unreachable
|
|
33 ;
|
|
34 entry:
|
|
35 br label %for.cond
|
|
36
|
|
37 for.cond: ; preds = %for.cond.cleanup3, %entry
|
|
38 %.lcssa10 = phi i16 [ 123, %entry ], [ %.lcssa, %for.cond.cleanup3 ]
|
|
39 %i.0 = phi i64 [ 0, %entry ], [ %inc9, %for.cond.cleanup3 ]
|
|
40 %ptr = getelementptr inbounds i16, i16* %A, i64 %i.0
|
|
41 %tmp2 = load i16, i16* %ptr
|
|
42 %cmp = icmp ult i64 %i.0, 3
|
|
43 br i1 %cmp, label %for.cond.cleanup3, label %for.cond.cleanup
|
|
44
|
|
45 for.cond.cleanup: ; preds = %for.cond
|
|
46 %.lcssa10.lcssa = phi i16 [ %.lcssa10, %for.cond ]
|
|
47 %tmp3 = call i16 (i16) @func(i16 %.lcssa10.lcssa)
|
|
48 ret i16 0
|
|
49
|
|
50 for.cond.cleanup3: ; preds = %for.cond
|
|
51 %.lcssa = phi i16 [ %tmp2, %for.cond ]
|
|
52 %inc9 = add i64 %i.0, 1
|
|
53 br label %for.cond
|
|
54 }
|
|
55
|
|
56 define i16 @partial_unroll(i16* %A) {
|
|
57 ; CHECK-LABEL: @partial_unroll(
|
|
58 ; CHECK-NEXT: entry:
|
|
59 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
|
60 ; CHECK: for.cond:
|
|
61 ; CHECK-NEXT: [[I_0:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INC9_2:%.*]], [[FOR_COND_CLEANUP3_2:%.*]] ]
|
|
62 ; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds i16, i16* [[A:%.*]], i64 [[I_0]]
|
173
|
63 ; CHECK-NEXT: [[TMP2:%.*]] = load i16, i16* [[PTR]], align 2
|
150
|
64 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP3:%.*]]
|
|
65 ; CHECK: for.cond.cleanup:
|
|
66 ; CHECK-NEXT: [[DOTLCSSA10_LCSSA:%.*]] = phi i16 [ [[TMP2_1:%.*]], [[FOR_COND_CLEANUP3_1:%.*]] ]
|
|
67 ; CHECK-NEXT: [[TMP3:%.*]] = call i16 @func(i16 [[DOTLCSSA10_LCSSA]])
|
|
68 ; CHECK-NEXT: ret i16 0
|
|
69 ; CHECK: for.cond.cleanup3:
|
|
70 ; CHECK-NEXT: [[INC9:%.*]] = add nuw nsw i64 [[I_0]], 1
|
|
71 ; CHECK-NEXT: [[PTR_1:%.*]] = getelementptr inbounds i16, i16* [[A]], i64 [[INC9]]
|
173
|
72 ; CHECK-NEXT: [[TMP2_1]] = load i16, i16* [[PTR_1]], align 2
|
150
|
73 ; CHECK-NEXT: br label [[FOR_COND_CLEANUP3_1]]
|
|
74 ; CHECK: for.cond.cleanup3.1:
|
|
75 ; CHECK-NEXT: [[INC9_1:%.*]] = add nuw nsw i64 [[INC9]], 1
|
|
76 ; CHECK-NEXT: [[PTR_2:%.*]] = getelementptr inbounds i16, i16* [[A]], i64 [[INC9_1]]
|
173
|
77 ; CHECK-NEXT: [[TMP2_2:%.*]] = load i16, i16* [[PTR_2]], align 2
|
150
|
78 ; CHECK-NEXT: [[CMP_2:%.*]] = icmp ult i64 [[INC9_1]], 200
|
|
79 ; CHECK-NEXT: br i1 [[CMP_2]], label [[FOR_COND_CLEANUP3_2]], label [[FOR_COND_CLEANUP:%.*]]
|
|
80 ; CHECK: for.cond.cleanup3.2:
|
|
81 ; CHECK-NEXT: [[INC9_2]] = add nuw nsw i64 [[INC9_1]], 1
|
|
82 ; CHECK-NEXT: br label [[FOR_COND]]
|
|
83 ;
|
|
84 entry:
|
|
85 br label %for.cond
|
|
86
|
|
87 for.cond: ; preds = %for.cond.cleanup3, %entry
|
|
88 %.lcssa10 = phi i16 [ 123, %entry ], [ %.lcssa, %for.cond.cleanup3 ]
|
|
89 %i.0 = phi i64 [ 0, %entry ], [ %inc9, %for.cond.cleanup3 ]
|
|
90 %ptr = getelementptr inbounds i16, i16* %A, i64 %i.0
|
|
91 %tmp2 = load i16, i16* %ptr
|
|
92 %cmp = icmp ult i64 %i.0, 200
|
|
93 br i1 %cmp, label %for.cond.cleanup3, label %for.cond.cleanup
|
|
94
|
|
95 for.cond.cleanup: ; preds = %for.cond
|
|
96 %.lcssa10.lcssa = phi i16 [ %.lcssa10, %for.cond ]
|
|
97 %tmp3 = call i16 (i16) @func(i16 %.lcssa10.lcssa)
|
|
98 ret i16 0
|
|
99
|
|
100 for.cond.cleanup3: ; preds = %for.cond
|
|
101 %.lcssa = phi i16 [ %tmp2, %for.cond ]
|
|
102 %inc9 = add i64 %i.0, 1
|
|
103 br label %for.cond
|
|
104 }
|
|
105
|
|
106 declare i16 @func(i16)
|
|
107
|