[libcxx] Use alias for detecting overriden function (#120805)
[llvm-project.git] / llvm / test / Transforms / LoopFusion / triple_loop_nest_inner_guard.ll
blob2ad211685aa4738fc4eda2358be088a5925ea16c
1 ; RUN: opt -S -passes=loop-fusion < %s 2>&1 | FileCheck %s
3 ; Verify that LoopFusion can fuse two triple-loop nests with guarded inner
4 ; loops. Loops are in canonical form.
6 @a = common global [10 x [10 x [10 x i32]]] zeroinitializer
7 @b = common global [10 x [10 x [10 x i32]]] zeroinitializer
8 @c = common global [10 x [10 x [10 x i32]]] zeroinitializer
10 ; CHECK-LABEL: @triple_loop_nest_inner_guard
11 ; CHECK: br i1 %{{.*}}, label %[[OUTER_PH:outer1.ph]], label %[[FUNC_EXIT:func_exit]]
13 ; CHECK: [[OUTER_PH]]:
14 ; CHECK: br label %[[OUTER_BODY_MIDDLE_GUARD:outer1.body.middle1.guard]]
16 ; CHECK: [[OUTER_BODY_MIDDLE_GUARD]]:
17 ; CHECK: br i1 %{{.*}}, label %[[MIDDLE_PH:middle1.ph]], label %[[OUTER_LATCH:outer2.latch]]
19 ; CHECK: [[MIDDLE_PH]]:
20 ; CHECK-NEXT: br label %[[MIDDLE_BODY_INNER_GUARD:middle1.body.inner1.guard]]
22 ; CHECK: [[MIDDLE_BODY_INNER_GUARD]]:
23 ; CHECK: br i1 %{{.*}}, label %[[INNER_PH:inner1.ph]], label %[[MIDDLE_LATCH:middle2.latch]]
25 ; CHECK: [[INNER_PH]]:
26 ; CHECK-NEXT: br label %[[INNER_BODY:inner1.body]]
28 ; CHECK: [[INNER_BODY]]:
29 ; First loop body.
30 ; CHECK: load
31 ; CHECK: add
32 ; CHECK: store
33 ; Second loop body.
34 ; CHECK: load
35 ; CHECK: mul
36 ; CHECK: store
37 ; CHECK: br i1 %{{.*}}, label %[[INNER_EXIT:inner2.exit]], label %[[INNER_BODY:inner1.body]]
39 ; CHECK: [[INNER_EXIT]]:
40 ; CHECK-NEXT: br label %[[MIDDLE_LATCH:middle2.latch]]
42 ; CHECK: [[MIDDLE_LATCH]]:
43 ; CHECK: br i1 %{{.*}}, label %[[MIDDLE_EXIT:middle2.exit]], label %[[MIDDLE_BODY_INNER_GUARD]]
45 ; CHECK: [[MIDDLE_EXIT]]:
46 ; CHECK-NEXT: br label %[[OUTER_LATCH:outer2.latch]]
48 ; CHECK: [[OUTER_LATCH]]:
49 ; CHECK: br i1 %{{.*}}, label %[[OUTER_EXIT:outer2.exit]], label %[[OUTER_BODY_MIDDLE_GUARD]]
51 ; CHECK: [[OUTER_EXIT]]:
52 ; CHECK-NEXT: br label %[[FUNC_EXIT:func_exit]]
54 ; CHECK: [[FUNC_EXIT]]:
55 ; CHECK-NEXT: ret
57 define i32 @triple_loop_nest_inner_guard(i32 %m, i32 %n, i32 %M, i32 %N) {
58 entry:
59   %cmp101 = icmp sgt i32 %m, 0
60   br i1 %cmp101, label %outer1.ph, label %func_exit
62 outer1.ph:
63   %cmp298 = icmp sgt i32 %n, 0
64   %cmp696 = icmp sgt i32 %M, 0
65   %wide.trip.count122 = zext i32 %m to i64
66   %wide.trip.count118 = zext i32 %n to i64
67   %wide.trip.count114 = zext i32 %M to i64
68   br label %outer1.body.middle1.guard
70 outer1.body.middle1.guard:
71   %iv120 = phi i64 [ 0, %outer1.ph ], [ %iv.next121, %outer1.latch ]
72   br i1 %cmp298, label %middle1.ph, label %outer1.latch
74 middle1.ph:
75   br label %middle1.body.inner1.guard
77 middle1.body.inner1.guard:
78   %iv116 = phi i64 [ %iv.next117, %middle1.latch ], [ 0, %middle1.ph ]
79   br i1 %cmp696, label %inner1.ph, label %middle1.latch
81 inner1.ph:
82   br label %inner1.body
84 inner1.body:
85   %iv112 = phi i64 [ %iv.next113, %inner1.body ], [ 0, %inner1.ph ]
86   %idx12 = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr @a, i64 0, i64 %iv120, i64 %iv116, i64 %iv112
87   %0 = load i32, ptr %idx12
88   %add = add nsw i32 %0, 2
89   %idx18 = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr @b, i64 0, i64 %iv120, i64 %iv116, i64 %iv112
90   store i32 %add, ptr %idx18
91   %iv.next113 = add nuw nsw i64 %iv112, 1
92   %exitcond115 = icmp eq i64 %iv.next113, %wide.trip.count114
93   br i1 %exitcond115, label %inner1.exit, label %inner1.body
95 inner1.exit:
96   br label %middle1.latch
98 middle1.latch:
99   %iv.next117 = add nuw nsw i64 %iv116, 1
100   %exitcond119 = icmp eq i64 %iv.next117, %wide.trip.count118
101   br i1 %exitcond119, label %middle1.exit, label %middle1.body.inner1.guard
103 middle1.exit:
104   br label %outer1.latch
106 outer1.latch:
107   %iv.next121 = add nuw nsw i64 %iv120, 1
108   %exitcond123 = icmp eq i64 %iv.next121, %wide.trip.count122
109   br i1 %exitcond123, label %outer2.ph, label %outer1.body.middle1.guard
111 outer2.ph:
112   br label %outer2.middle2.guard
114 outer2.middle2.guard:
115   %iv108 = phi i64 [ %iv.next109, %outer2.latch ], [ 0, %outer2.ph ]
116   br i1 %cmp298, label %middle2.ph, label %outer2.latch
118 middle2.ph:
119   br label %middle2.body.inner2.guard
121 middle2.body.inner2.guard:
122   %iv104 = phi i64 [ %iv.next105, %middle2.latch ], [ 0, %middle2.ph ]
123   br i1 %cmp696, label %inner2.ph, label %middle2.latch
125 inner2.ph:
126   br label %inner2.body
128 inner2.body:
129   %iv = phi i64 [ %iv.next, %inner2.body ], [ 0, %inner2.ph ]
130   %idx45 = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr @a, i64 0, i64 %iv108, i64 %iv104, i64 %iv
131   %1 = load i32, ptr %idx45
132   %mul = shl nsw i32 %1, 1
133   %idx51 = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr @c, i64 0, i64 %iv108, i64 %iv104, i64 %iv
134   store i32 %mul, ptr %idx51
135   %iv.next = add nuw nsw i64 %iv, 1
136   %exitcond = icmp eq i64 %iv.next, %wide.trip.count114
137   br i1 %exitcond, label %inner2.exit, label %inner2.body
139 inner2.exit:
140   br label %middle2.latch
142 middle2.latch:
143   %iv.next105 = add nuw nsw i64 %iv104, 1
144   %exitcond107 = icmp eq i64 %iv.next105, %wide.trip.count118
145   br i1 %exitcond107, label %middle2.exit, label %middle2.body.inner2.guard
147 middle2.exit:
148   br label %outer2.latch
150 outer2.latch:
151   %iv.next109 = add nuw nsw i64 %iv108, 1
152   %exitcond111 = icmp eq i64 %iv.next109, %wide.trip.count122
153   br i1 %exitcond111, label %outer2.exit, label %outer2.middle2.guard
155 outer2.exit:
156   br label %func_exit
158 func_exit:
159   ret i32 undef