1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2; RUN: opt -passes=attributor-cgscc -S < %s 2>&1 | FileCheck %s --check-prefixes=CHECK
3; RUN: opt -passes=attributor-cgscc -disable-output -attributor-print-dep < %s 2>&1 | FileCheck %s --check-prefixes=GRAPH
4; RUN: opt -passes=attributor-cgscc -disable-output -attributor-dump-dep-graph -attributor-depgraph-dot-filename-prefix=%t < %s 2>/dev/null
5; RUN: FileCheck %s -input-file=%t_0.dot --check-prefix=DOT
6
7; Test 0
8;
9; test copied from the attributor introduction video: checkAndAdvance(), and the C code is:
10; int *checkAndAdvance(int * __attribute__((aligned(16))) p) {
11;   if (*p == 0)
12;     return checkAndAdvance(p + 4);
13;   return p;
14; }
15;
16define i32* @checkAndAdvance(i32* align 16 %0) {
17; CHECK: Function Attrs: argmemonly nofree nosync nounwind readonly
18; CHECK-LABEL: define {{[^@]+}}@checkAndAdvance
19; CHECK-SAME: (i32* nofree noundef nonnull readonly align 16 dereferenceable(4) [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
20; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[TMP0]], align 16
21; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
22; CHECK-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
23; CHECK:       4:
24; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 4
25; CHECK-NEXT:    [[TMP6:%.*]] = call i32* @checkAndAdvance(i32* nofree nonnull readonly align 16 [[TMP5]]) #[[ATTR1:[0-9]+]]
26; CHECK-NEXT:    br label [[TMP8:%.*]]
27; CHECK:       7:
28; CHECK-NEXT:    br label [[TMP8]]
29; CHECK:       8:
30; CHECK-NEXT:    [[DOT0:%.*]] = phi i32* [ [[TMP5]], [[TMP4]] ], [ [[TMP0]], [[TMP7]] ]
31; CHECK-NEXT:    ret i32* [[DOT0]]
32;
33  %2 = load i32, i32* %0, align 4
34  %3 = icmp eq i32 %2, 0
35  br i1 %3, label %4, label %7
36
374:                                                ; preds = %1
38  %5 = getelementptr inbounds i32, i32* %0, i64 4
39  %6 = call i32* @checkAndAdvance(i32* %5)
40  br label %8
41
427:                                                ; preds = %1
43  br label %8
44
458:                                                ; preds = %7, %4
46  %.0 = phi i32* [ %6, %4 ], [ %0, %7 ]
47  ret i32* %.0
48}
49
50;
51; Check for graph
52;
53
54; GRAPH:      [AAIsDead] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state Live[#BB 4/4][#TBEP 0][#KDE 1]
55; GRAPH-EMPTY:
56; GRAPH-NEXT: [AAPotentialValues] for CtxI '  %3 = icmp eq i32 %2, 0' at position {flt: [@-1]} with state set-state(< {  %3 = icmp eq i32 %2, 0[3], } >)
57; GRAPH-EMPTY:
58; GRAPH-NEXT: [AAPotentialValues] for CtxI '  %2 = load i32, i32* %0, align 4' at position {flt: [@-1]} with state set-state(< {  %2 = load i32, i32* %0, align 4[3], } >)
59; GRAPH-EMPTY:
60; GRAPH-NEXT: [AAPotentialValues] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state set-state(< {i32* %0[3], } >)
61; GRAPH-EMPTY:
62; GRAPH-NEXT: [AAPotentialValues] for CtxI <<null inst>> at position {flt: [@-1]} with state set-state(< {i32 0[3], } >)
63; GRAPH-EMPTY:
64; GRAPH-NEXT: [AANoReturn] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state may-return
65; GRAPH-EMPTY:
66; GRAPH-NEXT: [AANoReturn] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state may-return
67; GRAPH-EMPTY:
68; GRAPH-NEXT: [AAIsDead] for CtxI '  ret i32* %.0' at position {flt: [@-1]} with state assumed-live
69; GRAPH-EMPTY:
70; GRAPH-NEXT: [AAWillReturn] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state may-noreturn
71; GRAPH-EMPTY:
72; GRAPH-NEXT: [AAIsDead] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {flt: [@-1]} with state assumed-live
73; GRAPH-EMPTY:
74; GRAPH-NEXT: [AANoUnwind] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
75; GRAPH-NEXT:   updates [AANoUnwind] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nounwind
76; GRAPH-NEXT:   updates [AANoUnwind] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nounwind
77; GRAPH-EMPTY:
78; GRAPH-NEXT: [AANoUnwind] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nounwind
79; GRAPH-NEXT:   updates [AANoUnwind] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
80; GRAPH-NEXT:   updates [AANoUnwind] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
81; GRAPH-NEXT:   updates [AANoCapture] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
82; GRAPH-NEXT:   updates [AANoUnwind] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
83; GRAPH-NEXT:   updates [AANoCapture] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
84; GRAPH-NEXT:   updates [AANoCapture] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
85; GRAPH-NEXT:   updates [AANoCapture] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
86; GRAPH-EMPTY:
87; GRAPH-NEXT: [AAMemoryLocation] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state memory:argument
88; GRAPH-NEXT:   updates [AAMemoryLocation] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state memory:argument
89; GRAPH-EMPTY:
90; GRAPH-NEXT: [AAMemoryLocation] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state memory:argument
91; GRAPH-NEXT:   updates [AAMemoryLocation] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state memory:argument
92; GRAPH-NEXT:   updates [AAMemoryLocation] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state memory:argument
93; GRAPH-EMPTY:
94; GRAPH-NEXT: [AAMemoryBehavior] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state readonly
95; GRAPH-NEXT:   updates [AAMemoryBehavior] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
96; GRAPH-NEXT:   updates [AANoCapture] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
97; GRAPH-NEXT:   updates [AAMemoryBehavior] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
98; GRAPH-NEXT:   updates [AAMemoryBehavior] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
99; GRAPH-NEXT:   updates [AANoCapture] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
100; GRAPH-NEXT:   updates [AAMemoryBehavior] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
101; GRAPH-NEXT:   updates [AANoCapture] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
102; GRAPH-NEXT:   updates [AAMemoryBehavior] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
103; GRAPH-NEXT:   updates [AANoCapture] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
104; GRAPH-EMPTY:
105; GRAPH-NEXT: [AAIsDead] for CtxI '  %2 = load i32, i32* %0, align 4' at position {flt: [@-1]} with state assumed-live
106; GRAPH-EMPTY:
107; GRAPH-NEXT: [AAIsDead] for CtxI '  %3 = icmp eq i32 %2, 0' at position {flt: [@-1]} with state assumed-live
108; GRAPH-EMPTY:
109; GRAPH-NEXT: [AAIsDead] for CtxI '  br i1 %3, label %4, label %7' at position {flt: [@-1]} with state assumed-live
110; GRAPH-EMPTY:
111; GRAPH-NEXT: [AAMemoryBehavior] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
112; GRAPH-NEXT:   updates [AAMemoryBehavior] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state readonly
113; GRAPH-NEXT:   updates [AAMemoryBehavior] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state readonly
114; GRAPH-EMPTY:
115; GRAPH-NEXT: [AAPotentialValues] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state set-state(< {  %5 = getelementptr inbounds i32, i32* %0, i64 4[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3], } >)
116; GRAPH-NEXT:   updates [AAPotentialValues] for CtxI '  %.0 = phi i32* [ %6, %4 ], [ %0, %7 ]' at position {flt:.0 [.0@-1]} with state set-state(< {i32* %0[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3], } >)
117; GRAPH-NEXT:   updates [AAPotentialValues] for CtxI '  %.0 = phi i32* [ %6, %4 ], [ %0, %7 ]' at position {flt:.0 [.0@-1]} with state set-state(< {i32* %0[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3], } >)
118; GRAPH-NEXT:   updates [AAPotentialValues] for CtxI '  %.0 = phi i32* [ %6, %4 ], [ %0, %7 ]' at position {flt:.0 [.0@-1]} with state set-state(< {i32* %0[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3], } >)
119; GRAPH-NEXT:   updates [AAPotentialValues] for CtxI '  %.0 = phi i32* [ %6, %4 ], [ %0, %7 ]' at position {flt:.0 [.0@-1]} with state set-state(< {i32* %0[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3], } >)
120; GRAPH-EMPTY:
121; GRAPH-NEXT: [AAPotentialValues] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state set-state(< {i32* %0[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3], } >)
122; GRAPH-NEXT:   updates [AAPotentialValues] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state set-state(< {  %5 = getelementptr inbounds i32, i32* %0, i64 4[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3], } >)
123; GRAPH-NEXT:   updates [AAPotentialValues] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state set-state(< {  %5 = getelementptr inbounds i32, i32* %0, i64 4[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3], } >)
124; GRAPH-EMPTY:
125; GRAPH-NEXT: [AAReturnedValues] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state may-return(#2)
126; GRAPH-NEXT:   updates [AANoCapture] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
127; GRAPH-NEXT:   updates [AANonNull] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state nonnull
128; GRAPH-NEXT:   updates [AAAlign] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state align<1-16>
129; GRAPH-NEXT:   updates [AAPotentialValues] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state set-state(< {i32* %0[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3], } >)
130; GRAPH-NEXT:   updates [AAPotentialValues] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state set-state(< {i32* %0[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3], } >)
131; GRAPH-EMPTY:
132; GRAPH-NEXT: [AAPotentialValues] for CtxI '  %.0 = phi i32* [ %6, %4 ], [ %0, %7 ]' at position {flt:.0 [.0@-1]} with state set-state(< {i32* %0[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3],   %5 = getelementptr inbounds i32, i32* %0, i64 4[3], } >)
133; GRAPH-NEXT:   updates [AAReturnedValues] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state may-return(#2)
134; GRAPH-EMPTY:
135; GRAPH-NEXT: [AAPotentialValues] for CtxI '  %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state set-state(< {  %5 = getelementptr inbounds i32, i32* %0, i64 4[3], } >)
136; GRAPH-EMPTY:
137; GRAPH-NEXT: [AAPotentialValues] for CtxI <<null inst>> at position {flt: [@-1]} with state set-state(< {i64 4[3], } >)
138; GRAPH-EMPTY:
139; GRAPH-NEXT: [AAPotentialValues] for CtxI '  %2 = load i32, i32* %0, align 4' at position {flt:checkAndAdvance [checkAndAdvance@-1]} with state set-state(< {@checkAndAdvance[3], } >)
140; GRAPH-EMPTY:
141; GRAPH-NEXT: [AAPotentialValues] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state set-state(< {  %5 = getelementptr inbounds i32, i32* %0, i64 4[3], } >)
142; GRAPH-EMPTY:
143; GRAPH-NEXT: [AAInstanceInfo] for CtxI '  %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state <unique [fAa]>
144; GRAPH-EMPTY:
145; GRAPH-NEXT: [AANoRecurse] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state may-recurse
146; GRAPH-EMPTY:
147; GRAPH-NEXT: [AAFunctionReachability] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state FunctionReachability [1,1]
148; GRAPH-EMPTY:
149; GRAPH-NEXT: [AACallEdges] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state CallEdges[0,1]
150; GRAPH-EMPTY:
151; GRAPH-NEXT: [AACallEdges] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state CallEdges[0,1]
152; GRAPH-EMPTY:
153; GRAPH-NEXT: [AAIsDead] for CtxI '  br label %8' at position {flt: [@-1]} with state assumed-live
154; GRAPH-EMPTY:
155; GRAPH-NEXT: [AAWillReturn] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state may-noreturn
156; GRAPH-EMPTY:
157; GRAPH-NEXT: [AANoRecurse] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state may-recurse
158; GRAPH-EMPTY:
159; GRAPH-NEXT: [AAUndefinedBehavior] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state undefined-behavior
160; GRAPH-EMPTY:
161; GRAPH-NEXT: [AANoUndef] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state may-undef-or-poison
162; GRAPH-EMPTY:
163; GRAPH-NEXT: [AANoUndef] for CtxI '  %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state may-undef-or-poison
164; GRAPH-EMPTY:
165; GRAPH-NEXT: [AAIsDead] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state assumed-live
166; GRAPH-EMPTY:
167; GRAPH-NEXT: [AANoUndef] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state may-undef-or-poison
168; GRAPH-EMPTY:
169; GRAPH-NEXT: [AANoUndef] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state noundef
170; GRAPH-EMPTY:
171; GRAPH-NEXT: [AANoSync] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nosync
172; GRAPH-NEXT:   updates [AANoSync] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nosync
173; GRAPH-NEXT:   updates [AANoSync] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nosync
174; GRAPH-EMPTY:
175; GRAPH-NEXT: [AANoSync] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nosync
176; GRAPH-NEXT:   updates [AANoSync] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nosync
177; GRAPH-NEXT:   updates [AANoSync] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nosync
178; GRAPH-EMPTY:
179; GRAPH-NEXT: [AANoFree] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nofree
180; GRAPH-NEXT:   updates [AANoFree] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nofree
181; GRAPH-NEXT:   updates [AANoFree] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state nofree
182; GRAPH-NEXT:   updates [AANoFree] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nofree
183; GRAPH-NEXT:   updates [AANoFree] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state nofree
184; GRAPH-EMPTY:
185; GRAPH-NEXT: [AANoFree] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nofree
186; GRAPH-NEXT:   updates [AANoFree] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nofree
187; GRAPH-NEXT:   updates [AANoFree] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nofree
188; GRAPH-EMPTY:
189; GRAPH-NEXT: [AAAssumptionInfo] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state Known [], Assumed []
190; GRAPH-EMPTY:
191; GRAPH-NEXT: [AAHeapToStack] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state [H2S] Mallocs Good/Bad: 0/0
192; GRAPH-EMPTY:
193; GRAPH-NEXT: [AAAlign] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state align<1-16>
194; GRAPH-EMPTY:
195; GRAPH-NEXT: [AAAlign] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state align<16-16>
196; GRAPH-EMPTY:
197; GRAPH-NEXT: [AAAlign] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state align<16-16>
198; GRAPH-EMPTY:
199; GRAPH-NEXT: [AAAlign] for CtxI '  %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state align<16-16>
200; GRAPH-EMPTY:
201; GRAPH-NEXT: [AANonNull] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state nonnull
202; GRAPH-EMPTY:
203; GRAPH-NEXT: [AANonNull] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state nonnull
204; GRAPH-EMPTY:
205; GRAPH-NEXT: [AANoAlias] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state may-alias
206; GRAPH-EMPTY:
207; GRAPH-NEXT: [AADereferenceable] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state unknown-dereferenceable
208; GRAPH-EMPTY:
209; GRAPH-NEXT: [AADereferenceable] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state dereferenceable<4-4>
210; GRAPH-NEXT:   updates [AADereferenceable] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state unknown-dereferenceable
211; GRAPH-EMPTY:
212; GRAPH-NEXT: [AADereferenceable] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state unknown-dereferenceable
213; GRAPH-EMPTY:
214; GRAPH-NEXT: [AANonNull] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state nonnull
215; GRAPH-EMPTY:
216; GRAPH-NEXT: [AANonNull] for CtxI '  %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state nonnull
217; GRAPH-NEXT:   updates [AANonNull] for CtxI '  %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state nonnull
218; GRAPH-NEXT:   updates [AANonNull] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state nonnull
219; GRAPH-NEXT:   updates [AANonNull] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state nonnull
220; GRAPH-NEXT:   updates [AANonNull] for CtxI '  %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state nonnull
221; GRAPH-NEXT:   updates [AANonNull] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state nonnull
222; GRAPH-EMPTY:
223; GRAPH-NEXT: [AAIsDead] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed-live
224; GRAPH-EMPTY:
225; GRAPH-NEXT: [AANoAlias] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state may-alias
226; GRAPH-EMPTY:
227; GRAPH-NEXT: [AANoCapture] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
228; GRAPH-NEXT:   updates [AANoCapture] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state assumed not-captured-maybe-returned
229; GRAPH-NEXT:   updates [AAMemoryBehavior] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
230; GRAPH-NEXT:   updates [AANoCapture] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state assumed not-captured-maybe-returned
231; GRAPH-NEXT:   updates [AANoCapture] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state assumed not-captured-maybe-returned
232; GRAPH-EMPTY:
233; GRAPH-NEXT: [AAIsDead] for CtxI '  %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state assumed-live
234; GRAPH-EMPTY:
235; GRAPH-NEXT: [AAIsDead] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state assumed-live
236; GRAPH-EMPTY:
237; GRAPH-NEXT: [AANoCapture] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state assumed not-captured-maybe-returned
238; GRAPH-NEXT:   updates [AANoCapture] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
239; GRAPH-NEXT:   updates [AANoCapture] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
240; GRAPH-EMPTY:
241; GRAPH-NEXT: [AAIsDead] for CtxI '  br label %8' at position {flt: [@-1]} with state assumed-live
242; GRAPH-EMPTY:
243; GRAPH-NEXT: [AAMemoryBehavior] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
244; GRAPH-NEXT:   updates [AAMemoryBehavior] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state readonly
245; GRAPH-NEXT:   updates [AAMemoryBehavior] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state readonly
246; GRAPH-EMPTY:
247; GRAPH-NEXT: [AAMemoryBehavior] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state readonly
248; GRAPH-NEXT:   updates [AAMemoryBehavior] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
249; GRAPH-NEXT:   updates [AAMemoryLocation] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state memory:argument
250; GRAPH-NEXT:   updates [AAMemoryLocation] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state memory:argument
251; GRAPH-NEXT:   updates [AAMemoryLocation] for CtxI '  %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state memory:argument
252; GRAPH-EMPTY:
253; GRAPH-NEXT: [AANoFree] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state nofree
254; GRAPH-NEXT:   updates [AANoFree] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state nofree
255; GRAPH-NEXT:   updates [AANoFree] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state nofree
256; GRAPH-EMPTY:
257; GRAPH-NEXT: [AAPrivatizablePtr] for CtxI '  %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state [no-priv]
258; GRAPH-EMPTY:
259; GRAPH-NEXT: [AAAssumptionInfo] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state Known [], Assumed []
260; GRAPH-EMPTY:
261; GRAPH-NEXT: [AANoAlias] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state may-alias
262; GRAPH-EMPTY:
263; GRAPH-NEXT: [AANoAlias] for CtxI '  %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state may-alias
264; GRAPH-EMPTY:
265; GRAPH-NEXT: [AANoFree] for CtxI '  %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state nofree
266; GRAPH-EMPTY:
267; GRAPH-NEXT: [AADereferenceable] for CtxI '  %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state unknown-dereferenceable
268
269; GRAPH-NOT: update
270
271;
272; Check for .dot file
273;
274; DOT-DAG: Node[[Node0:0x[a-z0-9]+]] [shape=record,label="{[AAIsDead]
275; DOT-DAG: Node[[Node1:0x[a-z0-9]+]] [shape=record,label="{[AAPotentialValues]
276; DOT-DAG: Node[[Node2:0x[a-z0-9]+]] [shape=record,label="{[AAPotentialValues]
277; DOT-DAG: Node[[Node3:0x[a-z0-9]+]] [shape=record,label="{[AAPotentialValues]
278; DOT-DAG: Node[[Node4:0x[a-z0-9]+]] [shape=record,label="{[AAPotentialValues]
279; DOT-DAG: Node[[Node5:0x[a-z0-9]+]] [shape=record,label="{[AANoReturn]
280; DOT-DAG: Node[[Node6:0x[a-z0-9]+]] [shape=record,label="{[AANoReturn]
281; DOT-DAG: Node[[Node7:0x[a-z0-9]+]] [shape=record,label="{[AAIsDead]
282; DOT-DAG: Node[[Node8:0x[a-z0-9]+]] [shape=record,label="{[AAWillReturn]
283; DOT-DAG: Node[[Node9:0x[a-z0-9]+]] [shape=record,label="{[AAIsDead]
284; DOT-DAG: Node[[Node10:0x[a-z0-9]+]] [shape=record,label="{[AANoUnwind]
285; DOT-DAG: Node[[Node11:0x[a-z0-9]+]] [shape=record,label="{[AANoUnwind]
286; DOT-DAG: Node[[Node12:0x[a-z0-9]+]] [shape=record,label="{[AAMemoryLocation]
287; DOT-DAG: Node[[Node13:0x[a-z0-9]+]] [shape=record,label="{[AAMemoryLocation]
288; DOT-DAG: Node[[Node14:0x[a-z0-9]+]] [shape=record,label="{[AAMemoryBehavior]
289; DOT-DAG: Node[[Node15:0x[a-z0-9]+]] [shape=record,label="{[AAIsDead]
290; DOT-DAG: Node[[Node16:0x[a-z0-9]+]] [shape=record,label="{[AAIsDead]
291; DOT-DAG: Node[[Node17:0x[a-z0-9]+]] [shape=record,label="{[AAIsDead]
292; DOT-DAG: Node[[Node18:0x[a-z0-9]+]] [shape=record,label="{[AAMemoryBehavior]
293; DOT-DAG: Node[[Node19:0x[a-z0-9]+]] [shape=record,label="{[AAPotentialValues]
294; DOT-DAG: Node[[Node20:0x[a-z0-9]+]] [shape=record,label="{[AAPotentialValues]
295; DOT-DAG: Node[[Node21:0x[a-z0-9]+]] [shape=record,label="{[AAReturnedValues]
296; DOT-DAG: Node[[Node22:0x[a-z0-9]+]] [shape=record,label="{[AAPotentialValues]
297; DOT-DAG: Node[[Node23:0x[a-z0-9]+]] [shape=record,label="{[AAPotentialValues]
298; DOT-DAG: Node[[Node24:0x[a-z0-9]+]] [shape=record,label="{[AAPotentialValues]
299; DOT-DAG: Node[[Node25:0x[a-z0-9]+]] [shape=record,label="{[AAPotentialValues]
300; DOT-DAG: Node[[Node26:0x[a-z0-9]+]] [shape=record,label="{[AAPotentialValues]
301; DOT-DAG: Node[[Node27:0x[a-z0-9]+]] [shape=record,label="{[AAInstanceInfo]
302; DOT-DAG: Node[[Node28:0x[a-z0-9]+]] [shape=record,label="{[AANoRecurse]
303; DOT-DAG: Node[[Node29:0x[a-z0-9]+]] [shape=record,label="{[AAFunctionReachability]
304; DOT-DAG: Node[[Node30:0x[a-z0-9]+]] [shape=record,label="{[AACallEdges]
305; DOT-DAG: Node[[Node31:0x[a-z0-9]+]] [shape=record,label="{[AACallEdges]
306; DOT-DAG: Node[[Node32:0x[a-z0-9]+]] [shape=record,label="{[AAIsDead]
307; DOT-DAG: Node[[Node33:0x[a-z0-9]+]] [shape=record,label="{[AAWillReturn]
308; DOT-DAG: Node[[Node34:0x[a-z0-9]+]] [shape=record,label="{[AANoRecurse]
309; DOT-DAG: Node[[Node35:0x[a-z0-9]+]] [shape=record,label="{[AAUndefinedBehavior]
310; DOT-DAG: Node[[Node36:0x[a-z0-9]+]] [shape=record,label="{[AANoUndef]
311; DOT-DAG: Node[[Node37:0x[a-z0-9]+]] [shape=record,label="{[AANoUndef]
312; DOT-DAG: Node[[Node38:0x[a-z0-9]+]] [shape=record,label="{[AAIsDead]
313; DOT-DAG: Node[[Node39:0x[a-z0-9]+]] [shape=record,label="{[AANoUndef]
314; DOT-DAG: Node[[Node40:0x[a-z0-9]+]] [shape=record,label="{[AANoUndef]
315; DOT-DAG: Node[[Node41:0x[a-z0-9]+]] [shape=record,label="{[AANoSync]
316; DOT-DAG: Node[[Node42:0x[a-z0-9]+]] [shape=record,label="{[AANoSync]
317; DOT-DAG: Node[[Node43:0x[a-z0-9]+]] [shape=record,label="{[AANoFree]
318; DOT-DAG: Node[[Node44:0x[a-z0-9]+]] [shape=record,label="{[AANoFree]
319; DOT-DAG: Node[[Node45:0x[a-z0-9]+]] [shape=record,label="{[AAAssumptionInfo]
320; DOT-DAG: Node[[Node46:0x[a-z0-9]+]] [shape=record,label="{[AAHeapToStack]
321; DOT-DAG: Node[[Node47:0x[a-z0-9]+]] [shape=record,label="{[AAAlign]
322; DOT-DAG: Node[[Node48:0x[a-z0-9]+]] [shape=record,label="{[AAAlign]
323; DOT-DAG: Node[[Node49:0x[a-z0-9]+]] [shape=record,label="{[AAAlign]
324; DOT-DAG: Node[[Node50:0x[a-z0-9]+]] [shape=record,label="{[AAAlign]
325; DOT-DAG: Node[[Node51:0x[a-z0-9]+]] [shape=record,label="{[AANonNull]
326; DOT-DAG: Node[[Node52:0x[a-z0-9]+]] [shape=record,label="{[AANonNull]
327; DOT-DAG: Node[[Node53:0x[a-z0-9]+]] [shape=record,label="{[AANoAlias]
328; DOT-DAG: Node[[Node54:0x[a-z0-9]+]] [shape=record,label="{[AADereferenceable]
329; DOT-DAG: Node[[Node55:0x[a-z0-9]+]] [shape=record,label="{[AADereferenceable]
330; DOT-DAG: Node[[Node56:0x[a-z0-9]+]] [shape=record,label="{[AADereferenceable]
331; DOT-DAG: Node[[Node57:0x[a-z0-9]+]] [shape=record,label="{[AANonNull]
332; DOT-DAG: Node[[Node58:0x[a-z0-9]+]] [shape=record,label="{[AANonNull]
333; DOT-DAG: Node[[Node59:0x[a-z0-9]+]] [shape=record,label="{[AAIsDead]
334; DOT-DAG: Node[[Node60:0x[a-z0-9]+]] [shape=record,label="{[AANoAlias]
335; DOT-DAG: Node[[Node61:0x[a-z0-9]+]] [shape=record,label="{[AANoCapture]
336; DOT-DAG: Node[[Node62:0x[a-z0-9]+]] [shape=record,label="{[AAIsDead]
337; DOT-DAG: Node[[Node63:0x[a-z0-9]+]] [shape=record,label="{[AAIsDead]
338; DOT-DAG: Node[[Node64:0x[a-z0-9]+]] [shape=record,label="{[AANoCapture]
339; DOT-DAG: Node[[Node65:0x[a-z0-9]+]] [shape=record,label="{[AAIsDead]
340; DOT-DAG: Node[[Node66:0x[a-z0-9]+]] [shape=record,label="{[AAMemoryBehavior]
341; DOT-DAG: Node[[Node67:0x[a-z0-9]+]] [shape=record,label="{[AAMemoryBehavior]
342; DOT-DAG: Node[[Node68:0x[a-z0-9]+]] [shape=record,label="{[AANoFree]
343; DOT-DAG: Node[[Node69:0x[a-z0-9]+]] [shape=record,label="{[AAPrivatizablePtr]
344; DOT-DAG: Node[[Node70:0x[a-z0-9]+]] [shape=record,label="{[AAAssumptionInfo]
345; DOT-DAG: Node[[Node71:0x[a-z0-9]+]] [shape=record,label="{[AANoAlias]
346; DOT-DAG: Node[[Node72:0x[a-z0-9]+]] [shape=record,label="{[AANoAlias]
347; DOT-DAG: Node[[Node73:0x[a-z0-9]+]] [shape=record,label="{[AANoFree]
348; DOT-DAG: Node[[Node74:0x[a-z0-9]+]] [shape=record,label="{[AADereferenceable]
349
350; DOT-DAG: Node[[Node20]] -> Node[[Node19]];
351; DOT-DAG: Node[[Node67]] -> Node[[Node13]];
352; DOT-DAG: Node[[Node58]] -> Node[[Node58]];
353; DOT-DAG: Node[[Node13]] -> Node[[Node12]];
354; DOT-DAG: Node[[Node55]] -> Node[[Node56]];
355; DOT-DAG: Node[[Node68]] -> Node[[Node73]];
356; DOT-DAG: Node[[Node61]] -> Node[[Node66]];
357; DOT-DAG: Node[[Node21]] -> Node[[Node20]];
358; DOT-DAG: Node[[Node64]] -> Node[[Node61]];
359; DOT-DAG: Node[[Node14]] -> Node[[Node61]];
360; DOT-DAG: Node[[Node61]] -> Node[[Node64]];
361; DOT-DAG: Node[[Node12]] -> Node[[Node13]];
362; DOT-DAG: Node[[Node11]] -> Node[[Node61]];
363; DOT-DAG: Node[[Node58]] -> Node[[Node51]];
364; DOT-DAG: Node[[Node14]] -> Node[[Node18]];
365; DOT-DAG: Node[[Node22]] -> Node[[Node21]];
366; DOT-DAG: Node[[Node43]] -> Node[[Node68]];
367; DOT-DAG: Node[[Node19]] -> Node[[Node22]];
368; DOT-DAG: Node[[Node21]] -> Node[[Node51]];
369; DOT-DAG: Node[[Node14]] -> Node[[Node66]];
370; DOT-DAG: Node[[Node10]] -> Node[[Node11]];
371; DOT-DAG: Node[[Node41]] -> Node[[Node42]];
372; DOT-DAG: Node[[Node42]] -> Node[[Node41]];
373; DOT-DAG: Node[[Node11]] -> Node[[Node10]];
374; DOT-DAG: Node[[Node21]] -> Node[[Node61]];
375; DOT-DAG: Node[[Node67]] -> Node[[Node66]];
376; DOT-DAG: Node[[Node18]] -> Node[[Node14]];
377; DOT-DAG: Node[[Node58]] -> Node[[Node57]];
378; DOT-DAG: Node[[Node66]] -> Node[[Node67]];
379; DOT-DAG: Node[[Node21]] -> Node[[Node47]];
380; DOT-DAG: Node[[Node44]] -> Node[[Node43]];
381; DOT-DAG: Node[[Node43]] -> Node[[Node44]];
382;.
383; CHECK: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind readonly }
384; CHECK: attributes #[[ATTR1]] = { nofree nosync nounwind readonly }
385;.
386