File: triple_loop_nest_inner_guard.ll

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 1,998,492 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (160 lines) | stat: -rw-r--r-- 5,101 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
; RUN: opt -S -passes=loop-fusion < %s 2>&1 | FileCheck %s

; Verify that LoopFusion can fuse two triple-loop nests with guarded inner
; loops. Loops are in canonical form.

@a = common global [10 x [10 x [10 x i32]]] zeroinitializer
@b = common global [10 x [10 x [10 x i32]]] zeroinitializer
@c = common global [10 x [10 x [10 x i32]]] zeroinitializer

; CHECK-LABEL: @triple_loop_nest_inner_guard
; CHECK: br i1 %{{.*}}, label %[[OUTER_PH:outer1.ph]], label %[[FUNC_EXIT:func_exit]]

; CHECK: [[OUTER_PH]]:
; CHECK: br label %[[OUTER_BODY_MIDDLE_GUARD:outer1.body.middle1.guard]]

; CHECK: [[OUTER_BODY_MIDDLE_GUARD]]:
; CHECK: br i1 %{{.*}}, label %[[MIDDLE_PH:middle1.ph]], label %[[OUTER_LATCH:outer2.latch]]

; CHECK: [[MIDDLE_PH]]:
; CHECK-NEXT: br label %[[MIDDLE_BODY_INNER_GUARD:middle1.body.inner1.guard]]

; CHECK: [[MIDDLE_BODY_INNER_GUARD]]:
; CHECK: br i1 %{{.*}}, label %[[INNER_PH:inner1.ph]], label %[[MIDDLE_LATCH:middle2.latch]]

; CHECK: [[INNER_PH]]:
; CHECK-NEXT: br label %[[INNER_BODY:inner1.body]]

; CHECK: [[INNER_BODY]]:
; First loop body.
; CHECK: load
; CHECK: add
; CHECK: store
; Second loop body.
; CHECK: load
; CHECK: mul
; CHECK: store
; CHECK: br i1 %{{.*}}, label %[[INNER_EXIT:inner2.exit]], label %[[INNER_BODY:inner1.body]]

; CHECK: [[INNER_EXIT]]:
; CHECK-NEXT: br label %[[MIDDLE_LATCH:middle2.latch]]

; CHECK: [[MIDDLE_LATCH]]:
; CHECK: br i1 %{{.*}}, label %[[MIDDLE_EXIT:middle2.exit]], label %[[MIDDLE_BODY_INNER_GUARD]]

; CHECK: [[MIDDLE_EXIT]]:
; CHECK-NEXT: br label %[[OUTER_LATCH:outer2.latch]]

; CHECK: [[OUTER_LATCH]]:
; CHECK: br i1 %{{.*}}, label %[[OUTER_EXIT:outer2.exit]], label %[[OUTER_BODY_MIDDLE_GUARD]]

; CHECK: [[OUTER_EXIT]]:
; CHECK-NEXT: br label %[[FUNC_EXIT:func_exit]]

; CHECK: [[FUNC_EXIT]]:
; CHECK-NEXT: ret

define i32 @triple_loop_nest_inner_guard(i32 %m, i32 %n, i32 %M, i32 %N) {
entry:
  %cmp101 = icmp sgt i32 %m, 0
  br i1 %cmp101, label %outer1.ph, label %func_exit

outer1.ph:
  %cmp298 = icmp sgt i32 %n, 0
  %cmp696 = icmp sgt i32 %M, 0
  %wide.trip.count122 = zext i32 %m to i64
  %wide.trip.count118 = zext i32 %n to i64
  %wide.trip.count114 = zext i32 %M to i64
  br label %outer1.body.middle1.guard

outer1.body.middle1.guard:
  %iv120 = phi i64 [ 0, %outer1.ph ], [ %iv.next121, %outer1.latch ]
  br i1 %cmp298, label %middle1.ph, label %outer1.latch

middle1.ph:
  br label %middle1.body.inner1.guard

middle1.body.inner1.guard:
  %iv116 = phi i64 [ %iv.next117, %middle1.latch ], [ 0, %middle1.ph ]
  br i1 %cmp696, label %inner1.ph, label %middle1.latch

inner1.ph:
  br label %inner1.body

inner1.body:
  %iv112 = phi i64 [ %iv.next113, %inner1.body ], [ 0, %inner1.ph ]
  %idx12 = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr @a, i64 0, i64 %iv120, i64 %iv116, i64 %iv112
  %0 = load i32, ptr %idx12
  %add = add nsw i32 %0, 2
  %idx18 = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr @b, i64 0, i64 %iv120, i64 %iv116, i64 %iv112
  store i32 %add, ptr %idx18
  %iv.next113 = add nuw nsw i64 %iv112, 1
  %exitcond115 = icmp eq i64 %iv.next113, %wide.trip.count114
  br i1 %exitcond115, label %inner1.exit, label %inner1.body

inner1.exit:
  br label %middle1.latch

middle1.latch:
  %iv.next117 = add nuw nsw i64 %iv116, 1
  %exitcond119 = icmp eq i64 %iv.next117, %wide.trip.count118
  br i1 %exitcond119, label %middle1.exit, label %middle1.body.inner1.guard

middle1.exit:
  br label %outer1.latch

outer1.latch:
  %iv.next121 = add nuw nsw i64 %iv120, 1
  %exitcond123 = icmp eq i64 %iv.next121, %wide.trip.count122
  br i1 %exitcond123, label %outer2.ph, label %outer1.body.middle1.guard

outer2.ph:
  br label %outer2.middle2.guard

outer2.middle2.guard:
  %iv108 = phi i64 [ %iv.next109, %outer2.latch ], [ 0, %outer2.ph ]
  br i1 %cmp298, label %middle2.ph, label %outer2.latch

middle2.ph:
  br label %middle2.body.inner2.guard

middle2.body.inner2.guard:
  %iv104 = phi i64 [ %iv.next105, %middle2.latch ], [ 0, %middle2.ph ]
  br i1 %cmp696, label %inner2.ph, label %middle2.latch

inner2.ph:
  br label %inner2.body

inner2.body:
  %iv = phi i64 [ %iv.next, %inner2.body ], [ 0, %inner2.ph ]
  %idx45 = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr @a, i64 0, i64 %iv108, i64 %iv104, i64 %iv
  %1 = load i32, ptr %idx45
  %mul = shl nsw i32 %1, 1
  %idx51 = getelementptr inbounds [10 x [10 x [10 x i32]]], ptr @c, i64 0, i64 %iv108, i64 %iv104, i64 %iv
  store i32 %mul, ptr %idx51
  %iv.next = add nuw nsw i64 %iv, 1
  %exitcond = icmp eq i64 %iv.next, %wide.trip.count114
  br i1 %exitcond, label %inner2.exit, label %inner2.body

inner2.exit:
  br label %middle2.latch

middle2.latch:
  %iv.next105 = add nuw nsw i64 %iv104, 1
  %exitcond107 = icmp eq i64 %iv.next105, %wide.trip.count118
  br i1 %exitcond107, label %middle2.exit, label %middle2.body.inner2.guard

middle2.exit:
  br label %outer2.latch

outer2.latch:
  %iv.next109 = add nuw nsw i64 %iv108, 1
  %exitcond111 = icmp eq i64 %iv.next109, %wide.trip.count122
  br i1 %exitcond111, label %outer2.exit, label %outer2.middle2.guard

outer2.exit:
  br label %func_exit

func_exit:
  ret i32 undef
}