@@ -101,3 +101,65 @@ outer.crit_edge: ; preds = %outer.latch
101
101
for.cond.cleanup: ; preds = %outer.crit_edge, %entry
102
102
ret void
103
103
}
104
+
105
+ @global = external local_unnamed_addr global [4 x [4 x [2 x i16 ]]] align 16
106
+
107
+ ; %N.ext is defined in the outer loop header and used in the inner loop. After
108
+ ; interchanging, it will be defined in the new inner loop and used in the new;
109
+ ; outer latch, so we need to create a new LCSSA phi node for it.
110
+
111
+ define void @test2 (i32 %N ) {
112
+ ; CHECK-LABEL: @test2(
113
+ ; CHECK-NEXT: bb:
114
+ ; CHECK-NEXT: br label [[INNER_PREHEADER:%.*]]
115
+ ; CHECK: outer.header.preheader:
116
+ ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]]
117
+ ; CHECK: outer.header:
118
+ ; CHECK-NEXT: [[OUTER_IV:%.*]] = phi i64 [ [[OUTER_IV_NEXT:%.*]], [[OUTER_LATCH:%.*]] ], [ 0, [[OUTER_HEADER_PREHEADER:%.*]] ]
119
+ ; CHECK-NEXT: [[N_EXT:%.*]] = sext i32 [[N:%.*]] to i64
120
+ ; CHECK-NEXT: br label [[INNER_SPLIT1:%.*]]
121
+ ; CHECK: inner.preheader:
122
+ ; CHECK-NEXT: br label [[INNER:%.*]]
123
+ ; CHECK: inner:
124
+ ; CHECK-NEXT: [[INNER_IV:%.*]] = phi i64 [ [[TMP0:%.*]], [[INNER_SPLIT:%.*]] ], [ 0, [[INNER_PREHEADER]] ]
125
+ ; CHECK-NEXT: br label [[OUTER_HEADER_PREHEADER]]
126
+ ; CHECK: inner.split1:
127
+ ; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds [4 x [4 x [2 x i16]]], [4 x [4 x [2 x i16]]]* @global, i64 0, i64 [[INNER_IV]], i64 [[OUTER_IV]], i64 0
128
+ ; CHECK-NEXT: [[INNER_IV_NEXT:%.*]] = add nsw i64 [[INNER_IV]], 1
129
+ ; CHECK-NEXT: [[C_1:%.*]] = icmp ne i64 [[INNER_IV_NEXT]], [[N_EXT]]
130
+ ; CHECK-NEXT: br label [[OUTER_LATCH]]
131
+ ; CHECK: inner.split:
132
+ ; CHECK-NEXT: [[N_EXT_LCSSA:%.*]] = phi i64 [ [[N_EXT]], [[OUTER_LATCH]] ]
133
+ ; CHECK-NEXT: [[TMP0]] = add nsw i64 [[INNER_IV]], 1
134
+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[TMP0]], [[N_EXT_LCSSA]]
135
+ ; CHECK-NEXT: br i1 [[TMP1]], label [[INNER]], label [[EXIT:%.*]]
136
+ ; CHECK: outer.latch:
137
+ ; CHECK-NEXT: [[OUTER_IV_NEXT]] = add nsw i64 [[OUTER_IV]], 1
138
+ ; CHECK-NEXT: [[C_2:%.*]] = icmp ne i64 [[OUTER_IV]], [[N_EXT]]
139
+ ; CHECK-NEXT: br i1 [[C_2]], label [[OUTER_HEADER]], label [[INNER_SPLIT]]
140
+ ; CHECK: exit:
141
+ ; CHECK-NEXT: ret void
142
+ ;
143
+ bb:
144
+ br label %outer.header
145
+
146
+ outer.header: ; preds = %bb11, %bb2
147
+ %outer.iv = phi i64 [ 0 , %bb ], [ %outer.iv.next , %outer.latch ]
148
+ %N.ext = sext i32 %N to i64
149
+ br label %inner
150
+
151
+ inner: ; preds = %bb6, %bb4
152
+ %inner.iv = phi i64 [ 0 , %outer.header ], [ %inner.iv.next , %inner ]
153
+ %tmp8 = getelementptr inbounds [4 x [4 x [2 x i16 ]]], [4 x [4 x [2 x i16 ]]]* @global , i64 0 , i64 %inner.iv , i64 %outer.iv , i64 0
154
+ %inner.iv.next = add nsw i64 %inner.iv , 1
155
+ %c.1 = icmp ne i64 %inner.iv.next , %N.ext
156
+ br i1 %c.1 , label %inner , label %outer.latch
157
+
158
+ outer.latch: ; preds = %bb6
159
+ %outer.iv.next = add nsw i64 %outer.iv , 1
160
+ %c.2 = icmp ne i64 %outer.iv , %N.ext
161
+ br i1 %c.2 , label %outer.header , label %exit
162
+
163
+ exit: ; preds = %bb11
164
+ ret void
165
+ }
0 commit comments