1; RUN: opt < %s -disable-output "-passes=print<ddg>" 2>&1 | FileCheck %s
2
3; CHECK-LABEL: 'DDG' for loop 'test1.for.body':
4
5; CHECK: Node Address:[[PI:0x[0-9a-f]*]]:pi-block
6; CHECK-NEXT: --- start of nodes in pi-block ---
7; CHECK: Node Address:[[N1:0x[0-9a-f]*]]:single-instruction
8; CHECK-NEXT: Instructions:
9; CHECK-NEXT:    %i.02 = phi i64 [ %inc, %test1.for.body ], [ 0, %test1.for.body.preheader ]
10; CHECK-NEXT: Edges:
11; CHECK-NEXT:  [def-use] to [[N2:0x[0-9a-f]*]]
12
13; CHECK: Node Address:[[N2]]:single-instruction
14; CHECK-NEXT: Instructions:
15; CHECK-NEXT:    %inc = add i64 %i.02, 1
16; CHECK-NEXT: Edges:
17; CHECK-NEXT:  [def-use] to [[N1]]
18; CHECK-NEXT: --- end of nodes in pi-block ---
19; CHECK-NEXT: Edges:
20; CHECK-NEXT:  [def-use] to [[N3:0x[0-9a-f]*]]
21; CHECK-NEXT:  [def-use] to [[N4:0x[0-9a-f]*]]
22; CHECK-NEXT:  [def-use] to [[N5:0x[0-9a-f]*]]
23
24; CHECK: Node Address:[[N5]]:multi-instruction
25; CHECK-NEXT: Instructions:
26; CHECK-NEXT:    %exitcond = icmp ne i64 %inc, %n
27; CHECK-NEXT:    br i1 %exitcond, label %test1.for.body, label %for.end.loopexit
28; CHECK-NEXT: Edges:none!
29
30; CHECK: Node Address:[[N4]]:single-instruction
31; CHECK-NEXT: Instructions:
32; CHECK-NEXT:    %arrayidx1 = getelementptr inbounds float, float* %a, i64 %i.02
33; CHECK-NEXT: Edges:
34; CHECK-NEXT:  [def-use] to [[N6:0x[0-9a-f]*]]
35
36; CHECK: Node Address:[[N3]]:multi-instruction
37; CHECK-NEXT: Instructions:
38; CHECK-NEXT:    %arrayidx = getelementptr inbounds float, float* %b, i64 %i.02
39; CHECK-NEXT:    %0 = load float, float* %arrayidx, align 4
40; CHECK-NEXT: Edges:
41; CHECK-NEXT:  [def-use] to [[N7:0x[0-9a-f]*]]
42
43; CHECK: Node Address:[[N8:0x[0-9a-f]*]]:single-instruction
44; CHECK-NEXT: Instructions:
45; CHECK-NEXT:    %conv = uitofp i64 %n to float
46; CHECK-NEXT: Edges:
47; CHECK-NEXT:  [def-use] to [[N7]]
48
49; CHECK: Node Address:[[N7]]:single-instruction
50; CHECK-NEXT: Instructions:
51; CHECK-NEXT:    %add = fadd float %0, %conv
52; CHECK-NEXT: Edges:
53; CHECK-NEXT:  [def-use] to [[N6]]
54
55; CHECK: Node Address:[[N6]]:single-instruction
56; CHECK-NEXT: Instructions:
57; CHECK-NEXT:    store float %add, float* %arrayidx1, align 4
58; CHECK-NEXT: Edges:none!
59
60
61;; No memory dependencies.
62;; void test1(unsigned long n, float * restrict a, float * restrict b) {
63;;  for (unsigned long i = 0; i < n; i++)
64;;    a[i] = b[i] + n;
65;; }
66
67define void @test1(i64 %n, float* noalias %a, float* noalias %b) {
68entry:
69  %exitcond1 = icmp ne i64 0, %n
70  br i1 %exitcond1, label %test1.for.body, label %for.end
71
72test1.for.body:                                         ; preds = %entry, %test1.for.body
73  %i.02 = phi i64 [ %inc, %test1.for.body ], [ 0, %entry ]
74  %arrayidx = getelementptr inbounds float, float* %b, i64 %i.02
75  %0 = load float, float* %arrayidx, align 4
76  %conv = uitofp i64 %n to float
77  %add = fadd float %0, %conv
78  %arrayidx1 = getelementptr inbounds float, float* %a, i64 %i.02
79  store float %add, float* %arrayidx1, align 4
80  %inc = add i64 %i.02, 1
81  %exitcond = icmp ne i64 %inc, %n
82  br i1 %exitcond, label %test1.for.body, label %for.end
83
84for.end:                                          ; preds = %test1.for.body, %entry
85  ret void
86}
87
88
89; CHECK-LABEL: 'DDG' for loop 'test2.for.body':
90
91; CHECK: Node Address:[[PI:0x[0-9a-f]*]]:pi-block
92; CHECK-NEXT: --- start of nodes in pi-block ---
93; CHECK: Node Address:[[N1:0x[0-9a-f]*]]:single-instruction
94; CHECK-NEXT: Instructions:
95; CHECK-NEXT:    %i.02 = phi i64 [ %inc, %test2.for.body ], [ 0, %test2.for.body.preheader ]
96; CHECK-NEXT: Edges:
97; CHECK-NEXT:  [def-use] to [[N2:0x[0-9a-f]*]]
98
99; CHECK: Node Address:[[N2]]:single-instruction
100; CHECK-NEXT: Instructions:
101; CHECK-NEXT:    %inc = add i64 %i.02, 1
102; CHECK-NEXT: Edges:
103; CHECK-NEXT:  [def-use] to [[N1]]
104; CHECK-NEXT: --- end of nodes in pi-block ---
105; CHECK-NEXT: Edges:
106; CHECK-NEXT:  [def-use] to [[N3:0x[0-9a-f]*]]
107; CHECK-NEXT:  [def-use] to [[N4:0x[0-9a-f]*]]
108; CHECK-NEXT:  [def-use] to [[N5:0x[0-9a-f]*]]
109; CHECK-NEXT:  [def-use] to [[N6:0x[0-9a-f]*]]
110
111; CHECK: Node Address:[[N6]]:multi-instruction
112; CHECK-NEXT: Instructions:
113; CHECK-NEXT:    %exitcond = icmp ne i64 %inc, %n
114; CHECK-NEXT:    br i1 %exitcond, label %test2.for.body, label %for.end.loopexit
115; CHECK-NEXT: Edges:none!
116
117; CHECK: Node Address:[[N5]]:single-instruction
118; CHECK-NEXT: Instructions:
119; CHECK-NEXT:    %arrayidx2 = getelementptr inbounds float, float* %a, i64 %i.02
120; CHECK-NEXT: Edges:
121; CHECK-NEXT:  [def-use] to [[N7:0x[0-9a-f]*]]
122
123; CHECK: Node Address:[[N4]]:multi-instruction
124; CHECK-NEXT: Instructions:
125; CHECK-NEXT:    %arrayidx1 = getelementptr inbounds float, float* %a, i64 %i.02
126; CHECK-NEXT:    %1 = load float, float* %arrayidx1, align 4
127; CHECK-NEXT: Edges:
128; CHECK-NEXT:  [def-use] to [[N8:0x[0-9a-f]*]]
129; CHECK-NEXT:  [memory] to [[N7]]
130
131; CHECK: Node Address:[[N3]]:multi-instruction
132; CHECK-NEXT: Instructions:
133; CHECK-NEXT:    %arrayidx = getelementptr inbounds float, float* %b, i64 %i.02
134; CHECK-NEXT:    %0 = load float, float* %arrayidx, align 4
135; CHECK-NEXT: Edges:
136; CHECK-NEXT:  [def-use] to [[N8]]
137
138; CHECK: Node Address:[[N8]]:single-instruction
139; CHECK-NEXT: Instructions:
140; CHECK-NEXT:    %add = fadd float %0, %1
141; CHECK-NEXT: Edges:
142; CHECK-NEXT:  [def-use] to [[N7]]
143
144; CHECK: Node Address:[[N7]]:single-instruction
145; CHECK-NEXT: Instructions:
146; CHECK-NEXT:    store float %add, float* %arrayidx2, align 4
147; CHECK-NEXT: Edges:none!
148
149
150
151;; Loop-independent memory dependencies.
152;; void test2(unsigned long n, float * restrict a, float * restrict b) {
153;;  for (unsigned long i = 0; i < n; i++)
154;;    a[i] = b[i] + a[i];
155;; }
156
157define void @test2(i64 %n, float* noalias %a, float* noalias %b) {
158entry:
159  %exitcond1 = icmp ne i64 0, %n
160  br i1 %exitcond1, label %test2.for.body, label %for.end
161
162test2.for.body:                                         ; preds = %entry, %test2.for.body
163  %i.02 = phi i64 [ %inc, %test2.for.body ], [ 0, %entry ]
164  %arrayidx = getelementptr inbounds float, float* %b, i64 %i.02
165  %0 = load float, float* %arrayidx, align 4
166  %arrayidx1 = getelementptr inbounds float, float* %a, i64 %i.02
167  %1 = load float, float* %arrayidx1, align 4
168  %add = fadd float %0, %1
169  %arrayidx2 = getelementptr inbounds float, float* %a, i64 %i.02
170  store float %add, float* %arrayidx2, align 4
171  %inc = add i64 %i.02, 1
172  %exitcond = icmp ne i64 %inc, %n
173  br i1 %exitcond, label %test2.for.body, label %for.end
174
175for.end:                                          ; preds = %test2.for.body, %entry
176  ret void
177}