1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
3; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
4; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
5; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
6;
7; Test cases specifically designed for the "returned" argument attribute.
8; We use FIXME's to indicate problems and missing attributes.
9;
10
11; TEST SCC test returning an integer value argument
12;
13; int scc_r1(int a, int b, int r);
14; int scc_r2(int a, int b, int r);
15;
16; __attribute__((noinline)) int sink_r0(int r) {
17;   return r;
18; }
19;
20; __attribute__((noinline)) int scc_r1(int a, int r, int b) {
21;   return scc_r2(r, a, sink_r0(r));
22; }
23;
24; __attribute__((noinline)) int scc_r2(int a, int b, int r) {
25;   if (a > b)
26;     return scc_r2(b, a, sink_r0(r));
27;   if (a < b)
28;     return scc_r1(sink_r0(b), scc_r2(scc_r1(a, b, r), scc_r1(a, scc_r2(r, r, r), r), scc_r2(a, b, r)), scc_r1(a, b, r));
29;   return a == b ? r : scc_r2(a, b, r);
30; }
31; __attribute__((noinline)) int scc_rX(int a, int b, int r) {
32;   if (a > b)
33;     return scc_r2(b, a, sink_r0(r));
34;   if (a < b)                                                                         // V Diff to scc_r2
35;     return scc_r1(sink_r0(b), scc_r2(scc_r1(a, b, r), scc_r1(a, scc_r2(r, r, r), r), scc_r1(a, b, r)), scc_r1(a, b, r));
36;   return a == b ? r : scc_r2(a, b, r);
37; }
38target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
39
40;.
41; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = external global i8
42; CHECK: @[[_ZTI1X:[a-zA-Z0-9_$"\\.-]+]] = external dso_local constant { i8*, i8* }, align 8
43; CHECK: @[[_ZTI1Y:[a-zA-Z0-9_$"\\.-]+]] = external dso_local constant { i8*, i8*, i8* }, align 8
44;.
45define i32 @sink_r0(i32 %r) #0 {
46; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
47; CHECK-LABEL: define {{[^@]+}}@sink_r0
48; CHECK-SAME: (i32 returned [[R:%.*]]) #[[ATTR0:[0-9]+]] {
49; CHECK-NEXT:  entry:
50; CHECK-NEXT:    ret i32 [[R]]
51;
52entry:
53  ret i32 %r
54}
55
56define i32 @scc_r1(i32 %a, i32 %r, i32 %b) #0 {
57; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
58; IS__TUNIT____-LABEL: define {{[^@]+}}@scc_r1
59; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] {
60; IS__TUNIT____-NEXT:  entry:
61; IS__TUNIT____-NEXT:    [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[R]]) #[[ATTR10:[0-9]+]]
62; IS__TUNIT____-NEXT:    ret i32 [[R]]
63;
64; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
65; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_r1
66; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] {
67; IS__CGSCC____-NEXT:  entry:
68; IS__CGSCC____-NEXT:    [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[R]]) #[[ATTR7:[0-9]+]]
69; IS__CGSCC____-NEXT:    ret i32 [[R]]
70;
71entry:
72  %call = call i32 @sink_r0(i32 %r)
73  %call1 = call i32 @scc_r2(i32 %r, i32 %a, i32 %call)
74  ret i32 %call1
75}
76
77define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 {
78; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
79; IS__TUNIT____-LABEL: define {{[^@]+}}@scc_r2
80; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) #[[ATTR1]] {
81; IS__TUNIT____-NEXT:  entry:
82; IS__TUNIT____-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
83; IS__TUNIT____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
84; IS__TUNIT____:       if.then:
85; IS__TUNIT____-NEXT:    [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR10]]
86; IS__TUNIT____-NEXT:    br label [[RETURN:%.*]]
87; IS__TUNIT____:       if.end:
88; IS__TUNIT____-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
89; IS__TUNIT____-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
90; IS__TUNIT____:       if.then3:
91; IS__TUNIT____-NEXT:    [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR10]]
92; IS__TUNIT____-NEXT:    [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR10]]
93; IS__TUNIT____-NEXT:    [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR10]]
94; IS__TUNIT____-NEXT:    [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR10]]
95; IS__TUNIT____-NEXT:    [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[R]]) #[[ATTR10]]
96; IS__TUNIT____-NEXT:    [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[R]], i32 undef) #[[ATTR10]]
97; IS__TUNIT____-NEXT:    br label [[RETURN]]
98; IS__TUNIT____:       if.end12:
99; IS__TUNIT____-NEXT:    [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
100; IS__TUNIT____-NEXT:    br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
101; IS__TUNIT____:       cond.true:
102; IS__TUNIT____-NEXT:    br label [[COND_END:%.*]]
103; IS__TUNIT____:       cond.false:
104; IS__TUNIT____-NEXT:    [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR10]]
105; IS__TUNIT____-NEXT:    br label [[COND_END]]
106; IS__TUNIT____:       cond.end:
107; IS__TUNIT____-NEXT:    [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
108; IS__TUNIT____-NEXT:    br label [[RETURN]]
109; IS__TUNIT____:       return:
110; IS__TUNIT____-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
111; IS__TUNIT____-NEXT:    ret i32 [[R]]
112;
113; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
114; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_r2
115; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) #[[ATTR1]] {
116; IS__CGSCC____-NEXT:  entry:
117; IS__CGSCC____-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
118; IS__CGSCC____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
119; IS__CGSCC____:       if.then:
120; IS__CGSCC____-NEXT:    [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR7]]
121; IS__CGSCC____-NEXT:    br label [[RETURN:%.*]]
122; IS__CGSCC____:       if.end:
123; IS__CGSCC____-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
124; IS__CGSCC____-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
125; IS__CGSCC____:       if.then3:
126; IS__CGSCC____-NEXT:    [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR7]]
127; IS__CGSCC____-NEXT:    [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR7]]
128; IS__CGSCC____-NEXT:    [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR7]]
129; IS__CGSCC____-NEXT:    [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR7]]
130; IS__CGSCC____-NEXT:    [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[R]]) #[[ATTR7]]
131; IS__CGSCC____-NEXT:    [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[R]], i32 undef) #[[ATTR7]]
132; IS__CGSCC____-NEXT:    br label [[RETURN]]
133; IS__CGSCC____:       if.end12:
134; IS__CGSCC____-NEXT:    [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
135; IS__CGSCC____-NEXT:    br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
136; IS__CGSCC____:       cond.true:
137; IS__CGSCC____-NEXT:    br label [[COND_END:%.*]]
138; IS__CGSCC____:       cond.false:
139; IS__CGSCC____-NEXT:    [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR7]]
140; IS__CGSCC____-NEXT:    br label [[COND_END]]
141; IS__CGSCC____:       cond.end:
142; IS__CGSCC____-NEXT:    [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
143; IS__CGSCC____-NEXT:    br label [[RETURN]]
144; IS__CGSCC____:       return:
145; IS__CGSCC____-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
146; IS__CGSCC____-NEXT:    ret i32 [[R]]
147;
148entry:
149  %cmp = icmp sgt i32 %a, %b
150  br i1 %cmp, label %if.then, label %if.end
151
152if.then:                                          ; preds = %entry
153  %call = call i32 @sink_r0(i32 %r)
154  %call1 = call i32 @scc_r2(i32 %b, i32 %a, i32 %call)
155  br label %return
156
157if.end:                                           ; preds = %entry
158  %cmp2 = icmp slt i32 %a, %b
159  br i1 %cmp2, label %if.then3, label %if.end12
160
161if.then3:                                         ; preds = %if.end
162  %call4 = call i32 @sink_r0(i32 %b)
163  %call5 = call i32 @scc_r1(i32 %a, i32 %b, i32 %r)
164  %call6 = call i32 @scc_r2(i32 %r, i32 %r, i32 %r)
165  %call7 = call i32 @scc_r1(i32 %a, i32 %call6, i32 %r)
166  %call8 = call i32 @scc_r2(i32 %a, i32 %b, i32 %r)
167  %call9 = call i32 @scc_r2(i32 %call5, i32 %call7, i32 %call8)
168  %call10 = call i32 @scc_r1(i32 %a, i32 %b, i32 %r)
169  %call11 = call i32 @scc_r1(i32 %call4, i32 %call9, i32 %call10)
170  br label %return
171
172if.end12:                                         ; preds = %if.end
173  %cmp13 = icmp eq i32 %a, %b
174  br i1 %cmp13, label %cond.true, label %cond.false
175
176cond.true:                                        ; preds = %if.end12
177  br label %cond.end
178
179cond.false:                                       ; preds = %if.end12
180  %call14 = call i32 @scc_r2(i32 %a, i32 %b, i32 %r)
181  br label %cond.end
182
183cond.end:                                         ; preds = %cond.false, %cond.true
184  %cond = phi i32 [ %r, %cond.true ], [ %call14, %cond.false ]
185  br label %return
186
187return:                                           ; preds = %cond.end, %if.then3, %if.then
188  %retval.0 = phi i32 [ %call1, %if.then ], [ %call11, %if.then3 ], [ %cond, %cond.end ]
189  ret i32 %retval.0
190}
191
192define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 {
193; IS__TUNIT____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
194; IS__TUNIT____-LABEL: define {{[^@]+}}@scc_rX
195; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) #[[ATTR2:[0-9]+]] {
196; IS__TUNIT____-NEXT:  entry:
197; IS__TUNIT____-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
198; IS__TUNIT____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
199; IS__TUNIT____:       if.then:
200; IS__TUNIT____-NEXT:    [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR10]]
201; IS__TUNIT____-NEXT:    br label [[RETURN:%.*]]
202; IS__TUNIT____:       if.end:
203; IS__TUNIT____-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
204; IS__TUNIT____-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
205; IS__TUNIT____:       if.then3:
206; IS__TUNIT____-NEXT:    [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR10]]
207; IS__TUNIT____-NEXT:    [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR10]]
208; IS__TUNIT____-NEXT:    [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR10]]
209; IS__TUNIT____-NEXT:    [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR10]]
210; IS__TUNIT____-NEXT:    [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[B]]) #[[ATTR10]]
211; IS__TUNIT____-NEXT:    [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[B]], i32 undef) #[[ATTR10]]
212; IS__TUNIT____-NEXT:    br label [[RETURN]]
213; IS__TUNIT____:       if.end12:
214; IS__TUNIT____-NEXT:    [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
215; IS__TUNIT____-NEXT:    br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
216; IS__TUNIT____:       cond.true:
217; IS__TUNIT____-NEXT:    br label [[COND_END:%.*]]
218; IS__TUNIT____:       cond.false:
219; IS__TUNIT____-NEXT:    [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR10]]
220; IS__TUNIT____-NEXT:    br label [[COND_END]]
221; IS__TUNIT____:       cond.end:
222; IS__TUNIT____-NEXT:    [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
223; IS__TUNIT____-NEXT:    br label [[RETURN]]
224; IS__TUNIT____:       return:
225; IS__TUNIT____-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[B]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
226; IS__TUNIT____-NEXT:    ret i32 [[RETVAL_0]]
227;
228; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
229; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_rX
230; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) #[[ATTR1]] {
231; IS__CGSCC____-NEXT:  entry:
232; IS__CGSCC____-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
233; IS__CGSCC____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
234; IS__CGSCC____:       if.then:
235; IS__CGSCC____-NEXT:    [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR8:[0-9]+]]
236; IS__CGSCC____-NEXT:    br label [[RETURN:%.*]]
237; IS__CGSCC____:       if.end:
238; IS__CGSCC____-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
239; IS__CGSCC____-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
240; IS__CGSCC____:       if.then3:
241; IS__CGSCC____-NEXT:    [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR8]]
242; IS__CGSCC____-NEXT:    [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR8]]
243; IS__CGSCC____-NEXT:    [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 [[R]]) #[[ATTR8]]
244; IS__CGSCC____-NEXT:    [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR8]]
245; IS__CGSCC____-NEXT:    [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[B]]) #[[ATTR8]]
246; IS__CGSCC____-NEXT:    [[CALL10:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR8]]
247; IS__CGSCC____-NEXT:    [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[B]], i32 [[B]]) #[[ATTR8]]
248; IS__CGSCC____-NEXT:    br label [[RETURN]]
249; IS__CGSCC____:       if.end12:
250; IS__CGSCC____-NEXT:    [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
251; IS__CGSCC____-NEXT:    br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
252; IS__CGSCC____:       cond.true:
253; IS__CGSCC____-NEXT:    br label [[COND_END:%.*]]
254; IS__CGSCC____:       cond.false:
255; IS__CGSCC____-NEXT:    [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR8]]
256; IS__CGSCC____-NEXT:    br label [[COND_END]]
257; IS__CGSCC____:       cond.end:
258; IS__CGSCC____-NEXT:    [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
259; IS__CGSCC____-NEXT:    br label [[RETURN]]
260; IS__CGSCC____:       return:
261; IS__CGSCC____-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
262; IS__CGSCC____-NEXT:    ret i32 [[RETVAL_0]]
263;
264entry:
265  %cmp = icmp sgt i32 %a, %b
266  br i1 %cmp, label %if.then, label %if.end
267
268if.then:                                          ; preds = %entry
269  %call = call i32 @sink_r0(i32 %r)
270  %call1 = call i32 @scc_r2(i32 %b, i32 %a, i32 %call)
271  br label %return
272
273if.end:                                           ; preds = %entry
274  %cmp2 = icmp slt i32 %a, %b
275  br i1 %cmp2, label %if.then3, label %if.end12
276
277if.then3:                                         ; preds = %if.end
278  %call4 = call i32 @sink_r0(i32 %b)
279  %call5 = call i32 @scc_r1(i32 %a, i32 %b, i32 %r)
280  %call6 = call i32 @scc_r2(i32 %r, i32 %r, i32 %r)
281  %call7 = call i32 @scc_r1(i32 %a, i32 %call6, i32 %r)
282  %call8 = call i32 @scc_r1(i32 %a, i32 %b, i32 %r)
283  %call9 = call i32 @scc_r2(i32 %call5, i32 %call7, i32 %call8)
284  %call10 = call i32 @scc_r1(i32 %a, i32 %b, i32 %r)
285  %call11 = call i32 @scc_r1(i32 %call4, i32 %call9, i32 %call10)
286  br label %return
287
288if.end12:                                         ; preds = %if.end
289  %cmp13 = icmp eq i32 %a, %b
290  br i1 %cmp13, label %cond.true, label %cond.false
291
292cond.true:                                        ; preds = %if.end12
293  br label %cond.end
294
295cond.false:                                       ; preds = %if.end12
296  %call14 = call i32 @scc_r2(i32 %a, i32 %b, i32 %r)
297  br label %cond.end
298
299cond.end:                                         ; preds = %cond.false, %cond.true
300  %cond = phi i32 [ %r, %cond.true ], [ %call14, %cond.false ]
301  br label %return
302
303return:                                           ; preds = %cond.end, %if.then3, %if.then
304  %retval.0 = phi i32 [ %call1, %if.then ], [ %call11, %if.then3 ], [ %cond, %cond.end ]
305  ret i32 %retval.0
306}
307
308
309; TEST SCC test returning a pointer value argument
310;
311; double* ptr_scc_r1(double* a, double* b, double* r);
312; double* ptr_scc_r2(double* a, double* b, double* r);
313;
314; __attribute__((noinline)) double* ptr_sink_r0(double* r) {
315;   return r;
316; }
317;
318; __attribute__((noinline)) double* ptr_scc_r1(double* a, double* r, double* b) {
319;   return ptr_scc_r2(r, a, ptr_sink_r0(r));
320; }
321;
322; __attribute__((noinline)) double* ptr_scc_r2(double* a, double* b, double* r) {
323;   if (a > b)
324;     return ptr_scc_r2(b, a, ptr_sink_r0(r));
325;   if (a < b)
326;     return ptr_scc_r1(ptr_sink_r0(b), ptr_scc_r2(ptr_scc_r1(a, b, r), ptr_scc_r1(a, ptr_scc_r2(r, r, r), r), ptr_scc_r2(a, b, r)), ptr_scc_r1(a, b, r));
327;   return a == b ? r : ptr_scc_r2(a, b, r);
328; }
329define double* @ptr_sink_r0(double* %r) #0 {
330; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
331; CHECK-LABEL: define {{[^@]+}}@ptr_sink_r0
332; CHECK-SAME: (double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR0]] {
333; CHECK-NEXT:  entry:
334; CHECK-NEXT:    ret double* [[R]]
335;
336entry:
337  ret double* %r
338}
339
340define double* @ptr_scc_r1(double* %a, double* %r, double* %b) #0 {
341; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
342; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_scc_r1
343; IS__TUNIT____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) #[[ATTR1]] {
344; IS__TUNIT____-NEXT:  entry:
345; IS__TUNIT____-NEXT:    [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]]
346; IS__TUNIT____-NEXT:    ret double* [[R]]
347;
348; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
349; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_scc_r1
350; IS__CGSCC____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nofree readnone returned [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) #[[ATTR1]] {
351; IS__CGSCC____-NEXT:  entry:
352; IS__CGSCC____-NEXT:    [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone [[R]]) #[[ATTR7]]
353; IS__CGSCC____-NEXT:    ret double* [[R]]
354;
355entry:
356  %call = call double* @ptr_sink_r0(double* %r)
357  %call1 = call double* @ptr_scc_r2(double* %r, double* %a, double* %call)
358  ret double* %call1
359}
360
361define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 {
362; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
363; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_scc_r2
364; IS__TUNIT____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nocapture nofree readnone [[B:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR1]] {
365; IS__TUNIT____-NEXT:  entry:
366; IS__TUNIT____-NEXT:    [[CMP:%.*]] = icmp ugt double* [[A]], [[B]]
367; IS__TUNIT____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
368; IS__TUNIT____:       if.then:
369; IS__TUNIT____-NEXT:    [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]]
370; IS__TUNIT____-NEXT:    br label [[RETURN:%.*]]
371; IS__TUNIT____:       if.end:
372; IS__TUNIT____-NEXT:    [[CMP2:%.*]] = icmp ult double* [[A]], [[B]]
373; IS__TUNIT____-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
374; IS__TUNIT____:       if.then3:
375; IS__TUNIT____-NEXT:    [[CALL5:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[B]], double* noalias nocapture nofree readnone undef) #[[ATTR10]]
376; IS__TUNIT____-NEXT:    [[CALL6:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]]
377; IS__TUNIT____-NEXT:    [[CALL7:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR10]]
378; IS__TUNIT____-NEXT:    [[CALL8:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]]
379; IS__TUNIT____-NEXT:    [[CALL9:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]]
380; IS__TUNIT____-NEXT:    [[CALL11:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR10]]
381; IS__TUNIT____-NEXT:    br label [[RETURN]]
382; IS__TUNIT____:       if.end12:
383; IS__TUNIT____-NEXT:    [[CMP13:%.*]] = icmp eq double* [[A]], [[B]]
384; IS__TUNIT____-NEXT:    br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
385; IS__TUNIT____:       cond.true:
386; IS__TUNIT____-NEXT:    br label [[COND_END:%.*]]
387; IS__TUNIT____:       cond.false:
388; IS__TUNIT____-NEXT:    [[CALL14:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR10]]
389; IS__TUNIT____-NEXT:    br label [[COND_END]]
390; IS__TUNIT____:       cond.end:
391; IS__TUNIT____-NEXT:    [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
392; IS__TUNIT____-NEXT:    br label [[RETURN]]
393; IS__TUNIT____:       return:
394; IS__TUNIT____-NEXT:    [[RETVAL_0:%.*]] = phi double* [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
395; IS__TUNIT____-NEXT:    ret double* [[R]]
396;
397; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
398; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_scc_r2
399; IS__CGSCC____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nocapture nofree readnone [[B:%.*]], double* nofree readnone returned [[R:%.*]]) #[[ATTR1]] {
400; IS__CGSCC____-NEXT:  entry:
401; IS__CGSCC____-NEXT:    [[CMP:%.*]] = icmp ugt double* [[A]], [[B]]
402; IS__CGSCC____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
403; IS__CGSCC____:       if.then:
404; IS__CGSCC____-NEXT:    [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone [[R]]) #[[ATTR7]]
405; IS__CGSCC____-NEXT:    br label [[RETURN:%.*]]
406; IS__CGSCC____:       if.end:
407; IS__CGSCC____-NEXT:    [[CMP2:%.*]] = icmp ult double* [[A]], [[B]]
408; IS__CGSCC____-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
409; IS__CGSCC____:       if.then3:
410; IS__CGSCC____-NEXT:    [[CALL5:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nocapture nofree readnone undef) #[[ATTR7]]
411; IS__CGSCC____-NEXT:    [[CALL6:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone [[R]]) #[[ATTR7]]
412; IS__CGSCC____-NEXT:    [[CALL7:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR7]]
413; IS__CGSCC____-NEXT:    [[CALL8:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone [[R]]) #[[ATTR7]]
414; IS__CGSCC____-NEXT:    [[CALL9:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone [[R]]) #[[ATTR7]]
415; IS__CGSCC____-NEXT:    [[CALL11:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR7]]
416; IS__CGSCC____-NEXT:    br label [[RETURN]]
417; IS__CGSCC____:       if.end12:
418; IS__CGSCC____-NEXT:    [[CMP13:%.*]] = icmp eq double* [[A]], [[B]]
419; IS__CGSCC____-NEXT:    br i1 [[CMP13]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
420; IS__CGSCC____:       cond.true:
421; IS__CGSCC____-NEXT:    br label [[COND_END:%.*]]
422; IS__CGSCC____:       cond.false:
423; IS__CGSCC____-NEXT:    [[CALL14:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone [[R]]) #[[ATTR7]]
424; IS__CGSCC____-NEXT:    br label [[COND_END]]
425; IS__CGSCC____:       cond.end:
426; IS__CGSCC____-NEXT:    [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
427; IS__CGSCC____-NEXT:    br label [[RETURN]]
428; IS__CGSCC____:       return:
429; IS__CGSCC____-NEXT:    [[RETVAL_0:%.*]] = phi double* [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
430; IS__CGSCC____-NEXT:    ret double* [[R]]
431;
432entry:
433  %cmp = icmp ugt double* %a, %b
434  br i1 %cmp, label %if.then, label %if.end
435
436if.then:                                          ; preds = %entry
437  %call = call double* @ptr_sink_r0(double* %r)
438  %call1 = call double* @ptr_scc_r2(double* %b, double* %a, double* %call)
439  br label %return
440
441if.end:                                           ; preds = %entry
442  %cmp2 = icmp ult double* %a, %b
443  br i1 %cmp2, label %if.then3, label %if.end12
444
445if.then3:                                         ; preds = %if.end
446  %call4 = call double* @ptr_sink_r0(double* %b)
447  %call5 = call double* @ptr_scc_r1(double* %a, double* %b, double* %r)
448  %call6 = call double* @ptr_scc_r2(double* %r, double* %r, double* %r)
449  %call7 = call double* @ptr_scc_r1(double* %a, double* %call6, double* %r)
450  %call8 = call double* @ptr_scc_r2(double* %a, double* %b, double* %r)
451  %call9 = call double* @ptr_scc_r2(double* %call5, double* %call7, double* %call8)
452  %call10 = call double* @ptr_scc_r1(double* %a, double* %b, double* %r)
453  %call11 = call double* @ptr_scc_r1(double* %call4, double* %call9, double* %call10)
454  br label %return
455
456if.end12:                                         ; preds = %if.end
457  %cmp13 = icmp eq double* %a, %b
458  br i1 %cmp13, label %cond.true, label %cond.false
459
460cond.true:                                        ; preds = %if.end12
461  br label %cond.end
462
463cond.false:                                       ; preds = %if.end12
464  %call14 = call double* @ptr_scc_r2(double* %a, double* %b, double* %r)
465  br label %cond.end
466
467cond.end:                                         ; preds = %cond.false, %cond.true
468  %cond = phi double* [ %r, %cond.true ], [ %call14, %cond.false ]
469  br label %return
470
471return:                                           ; preds = %cond.end, %if.then3, %if.then
472  %retval.0 = phi double* [ %call1, %if.then ], [ %call11, %if.then3 ], [ %cond, %cond.end ]
473  ret double* %retval.0
474}
475
476
477; TEST a no-return singleton SCC
478;
479; int* rt0(int *a) {
480;   return *a ? a : rt0(a);
481; }
482;
483define i32* @rt0(i32* %a) #0 {
484; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable
485; IS__TUNIT____-LABEL: define {{[^@]+}}@rt0
486; IS__TUNIT____-SAME: (i32* nofree noundef nonnull readonly returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR3:[0-9]+]] {
487; IS__TUNIT____-NEXT:  entry:
488; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call i32* @rt0(i32* nofree noundef nonnull readonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR11:[0-9]+]]
489; IS__TUNIT____-NEXT:    ret i32* [[A]]
490;
491; IS__CGSCC____: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable
492; IS__CGSCC____-LABEL: define {{[^@]+}}@rt0
493; IS__CGSCC____-SAME: (i32* nofree noundef nonnull readonly returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2:[0-9]+]] {
494; IS__CGSCC____-NEXT:  entry:
495; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call i32* @rt0(i32* nofree noundef nonnull readonly align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR9:[0-9]+]]
496; IS__CGSCC____-NEXT:    ret i32* [[A]]
497;
498entry:
499  %v = load i32, i32* %a, align 4
500  %tobool = icmp ne i32 %v, 0
501  %call = call i32* @rt0(i32* %a)
502  %sel = select i1 %tobool, i32* %a, i32* %call
503  ret i32* %sel
504}
505
506; TEST a no-return singleton SCC
507;
508; int* rt1(int *a) {
509;   return *a ? undef : rt1(a);
510; }
511;
512define i32* @rt1(i32* %a) #0 {
513; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable
514; IS__TUNIT____-LABEL: define {{[^@]+}}@rt1
515; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR4:[0-9]+]] {
516; IS__TUNIT____-NEXT:  entry:
517; IS__TUNIT____-NEXT:    ret i32* undef
518;
519; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable
520; IS__CGSCC____-LABEL: define {{[^@]+}}@rt1
521; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3:[0-9]+]] {
522; IS__CGSCC____-NEXT:  entry:
523; IS__CGSCC____-NEXT:    ret i32* undef
524;
525entry:
526  %v = load i32, i32* %a, align 4
527  %tobool = icmp ne i32 %v, 0
528  %call = call i32* @rt1(i32* %a)
529  %sel = select i1 %tobool, i32* undef, i32* %call
530  ret i32* %sel
531}
532
533; TEST another SCC test
534;
535define i32* @rt2_helper(i32* %a) #0 {
536; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
537; IS__TUNIT____-LABEL: define {{[^@]+}}@rt2_helper
538; IS__TUNIT____-SAME: (i32* nofree readnone returned [[A:%.*]]) #[[ATTR1]] {
539; IS__TUNIT____-NEXT:  entry:
540; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call i32* @rt2(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[A]]) #[[ATTR10]]
541; IS__TUNIT____-NEXT:    ret i32* [[A]]
542;
543; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
544; IS__CGSCC____-LABEL: define {{[^@]+}}@rt2_helper
545; IS__CGSCC____-SAME: (i32* nofree readnone returned [[A:%.*]]) #[[ATTR1]] {
546; IS__CGSCC____-NEXT:  entry:
547; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call i32* @rt2(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[A]]) #[[ATTR7]]
548; IS__CGSCC____-NEXT:    ret i32* [[A]]
549;
550entry:
551  %call = call i32* @rt2(i32* %a, i32* %a)
552  ret i32* %call
553}
554
555define i32* @rt2(i32* %a, i32 *%b) #0 {
556; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
557; IS__TUNIT____-LABEL: define {{[^@]+}}@rt2
558; IS__TUNIT____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
559; IS__TUNIT____-NEXT:  entry:
560; IS__TUNIT____-NEXT:    [[CMP:%.*]] = icmp eq i32* [[A]], null
561; IS__TUNIT____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
562; IS__TUNIT____:       if.then:
563; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call i32* @rt2_helper(i32* noalias nofree readnone [[A]]) #[[ATTR10]]
564; IS__TUNIT____-NEXT:    br label [[IF_END]]
565; IS__TUNIT____:       if.end:
566; IS__TUNIT____-NEXT:    [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[A]], [[IF_THEN]] ]
567; IS__TUNIT____-NEXT:    ret i32* [[SEL]]
568;
569; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
570; IS__CGSCC____-LABEL: define {{[^@]+}}@rt2
571; IS__CGSCC____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
572; IS__CGSCC____-NEXT:  entry:
573; IS__CGSCC____-NEXT:    [[CMP:%.*]] = icmp eq i32* [[A]], null
574; IS__CGSCC____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
575; IS__CGSCC____:       if.then:
576; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call i32* @rt2_helper(i32* noalias nofree readnone [[A]]) #[[ATTR7]]
577; IS__CGSCC____-NEXT:    br label [[IF_END]]
578; IS__CGSCC____:       if.end:
579; IS__CGSCC____-NEXT:    [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[A]], [[IF_THEN]] ]
580; IS__CGSCC____-NEXT:    ret i32* [[SEL]]
581;
582entry:
583  %cmp = icmp eq i32* %a, null
584  br i1 %cmp, label %if.then, label %if.end
585
586if.then:
587  %call = call i32* @rt2_helper(i32* %a)
588  br label %if.end
589
590if.end:
591  %sel = phi i32* [ %b, %entry], [%call, %if.then]
592  ret i32* %sel
593}
594
595; TEST another SCC test
596;
597define i32* @rt3_helper(i32* %a, i32* %b) #0 {
598; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
599; IS__TUNIT____-LABEL: define {{[^@]+}}@rt3_helper
600; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
601; IS__TUNIT____-NEXT:  entry:
602; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call i32* @rt3(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR10]]
603; IS__TUNIT____-NEXT:    ret i32* [[B]]
604;
605; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
606; IS__CGSCC____-LABEL: define {{[^@]+}}@rt3_helper
607; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
608; IS__CGSCC____-NEXT:  entry:
609; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call i32* @rt3(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR7]]
610; IS__CGSCC____-NEXT:    ret i32* [[B]]
611;
612entry:
613  %call = call i32* @rt3(i32* %a, i32* %b)
614  ret i32* %call
615}
616
617define i32* @rt3(i32* %a, i32 *%b) #0 {
618; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
619; IS__TUNIT____-LABEL: define {{[^@]+}}@rt3
620; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
621; IS__TUNIT____-NEXT:  entry:
622; IS__TUNIT____-NEXT:    [[CMP:%.*]] = icmp eq i32* [[A]], null
623; IS__TUNIT____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
624; IS__TUNIT____:       if.then:
625; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR10]]
626; IS__TUNIT____-NEXT:    br label [[IF_END]]
627; IS__TUNIT____:       if.end:
628; IS__TUNIT____-NEXT:    [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[B]], [[IF_THEN]] ]
629; IS__TUNIT____-NEXT:    ret i32* [[B]]
630;
631; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
632; IS__CGSCC____-LABEL: define {{[^@]+}}@rt3
633; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
634; IS__CGSCC____-NEXT:  entry:
635; IS__CGSCC____-NEXT:    [[CMP:%.*]] = icmp eq i32* [[A]], null
636; IS__CGSCC____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
637; IS__CGSCC____:       if.then:
638; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR7]]
639; IS__CGSCC____-NEXT:    br label [[IF_END]]
640; IS__CGSCC____:       if.end:
641; IS__CGSCC____-NEXT:    [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[B]], [[IF_THEN]] ]
642; IS__CGSCC____-NEXT:    ret i32* [[B]]
643;
644entry:
645  %cmp = icmp eq i32* %a, null
646  br i1 %cmp, label %if.then, label %if.end
647
648if.then:
649  %call = call i32* @rt3_helper(i32* %a, i32* %b)
650  br label %if.end
651
652if.end:
653  %sel = phi i32* [ %b, %entry], [%call, %if.then]
654  ret i32* %sel
655}
656
657; TEST address taken function with call to an external functions
658;
659;  void unknown_fn(void *);
660;
661;  int* calls_unknown_fn(int *r) {
662;    unknown_fn(&calls_unknown_fn);
663;    return r;
664;  }
665;
666declare void @unknown_fn(i32* (i32*)*) #0
667
668define i32* @calls_unknown_fn(i32* %r) #0 {
669; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
670; IS__TUNIT____-LABEL: define {{[^@]+}}@calls_unknown_fn
671; IS__TUNIT____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR5:[0-9]+]] {
672; IS__TUNIT____-NEXT:    tail call void @unknown_fn(i32* (i32*)* noundef nonnull @calls_unknown_fn) #[[ATTR12:[0-9]+]]
673; IS__TUNIT____-NEXT:    ret i32* [[R]]
674;
675; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
676; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_unknown_fn
677; IS__CGSCC____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR4:[0-9]+]] {
678; IS__CGSCC____-NEXT:    tail call void @unknown_fn(i32* (i32*)* noundef nonnull @calls_unknown_fn) #[[ATTR10:[0-9]+]]
679; IS__CGSCC____-NEXT:    ret i32* [[R]]
680;
681  tail call void @unknown_fn(i32* (i32*)* nonnull @calls_unknown_fn)
682  ret i32* %r
683}
684
685
686; TEST call to a function that might be redifined at link time
687;
688;  int *maybe_redefined_fn(int *r) {
689;    return r;
690;  }
691;
692;  int *calls_maybe_redefined_fn(int *r) {
693;    maybe_redefined_fn(r);
694;    return r;
695;  }
696;
697; Verify the maybe-redefined function is not annotated:
698;
699define linkonce_odr i32* @maybe_redefined_fn(i32* %r) #0 {
700; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
701; IS__TUNIT____-LABEL: define {{[^@]+}}@maybe_redefined_fn
702; IS__TUNIT____-SAME: (i32* [[R:%.*]]) #[[ATTR5]] {
703; IS__TUNIT____-NEXT:  entry:
704; IS__TUNIT____-NEXT:    ret i32* [[R]]
705;
706; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
707; IS__CGSCC____-LABEL: define {{[^@]+}}@maybe_redefined_fn
708; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR4]] {
709; IS__CGSCC____-NEXT:  entry:
710; IS__CGSCC____-NEXT:    ret i32* [[R]]
711;
712entry:
713  ret i32* %r
714}
715
716define i32* @calls_maybe_redefined_fn(i32* %r) #0 {
717; IS__TUNIT____: Function Attrs: noinline norecurse nounwind uwtable
718; IS__TUNIT____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn
719; IS__TUNIT____-SAME: (i32* returned [[R:%.*]]) #[[ATTR6:[0-9]+]] {
720; IS__TUNIT____-NEXT:  entry:
721; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR12]]
722; IS__TUNIT____-NEXT:    ret i32* [[R]]
723;
724; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
725; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn
726; IS__CGSCC____-SAME: (i32* returned [[R:%.*]]) #[[ATTR4]] {
727; IS__CGSCC____-NEXT:  entry:
728; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR10]]
729; IS__CGSCC____-NEXT:    ret i32* [[R]]
730;
731entry:
732  %call = call i32* @maybe_redefined_fn(i32* %r)
733  ret i32* %r
734}
735
736; TEST return call to a function that might be redifined at link time
737;
738;  int *maybe_redefined_fn2(int *r) {
739;    return r;
740;  }
741;
742;  int *calls_maybe_redefined_fn2(int *r) {
743;    return maybe_redefined_fn2(r);
744;  }
745;
746; Verify the maybe-redefined function is not annotated:
747;
748define linkonce_odr i32* @maybe_redefined_fn2(i32* %r) #0 {
749; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
750; IS__TUNIT____-LABEL: define {{[^@]+}}@maybe_redefined_fn2
751; IS__TUNIT____-SAME: (i32* [[R:%.*]]) #[[ATTR5]] {
752; IS__TUNIT____-NEXT:  entry:
753; IS__TUNIT____-NEXT:    ret i32* [[R]]
754;
755; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
756; IS__CGSCC____-LABEL: define {{[^@]+}}@maybe_redefined_fn2
757; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR4]] {
758; IS__CGSCC____-NEXT:  entry:
759; IS__CGSCC____-NEXT:    ret i32* [[R]]
760;
761entry:
762  ret i32* %r
763}
764
765define i32* @calls_maybe_redefined_fn2(i32* %r) #0 {
766; IS__TUNIT____: Function Attrs: noinline norecurse nounwind uwtable
767; IS__TUNIT____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn2
768; IS__TUNIT____-SAME: (i32* [[R:%.*]]) #[[ATTR6]] {
769; IS__TUNIT____-NEXT:  entry:
770; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR12]]
771; IS__TUNIT____-NEXT:    ret i32* [[CALL]]
772;
773; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
774; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn2
775; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR4]] {
776; IS__CGSCC____-NEXT:  entry:
777; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR10]]
778; IS__CGSCC____-NEXT:    ret i32* [[CALL]]
779;
780entry:
781  %call = call i32* @maybe_redefined_fn2(i32* %r)
782  ret i32* %call
783}
784
785
786; TEST returned argument goes through select and phi
787;
788; double select_and_phi(double b) {
789;   double x = b;
790;   if (b > 0)
791;     x = b;
792;   return b == 0? b : x;
793; }
794;
795define double @select_and_phi(double %b) #0 {
796; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
797; CHECK-LABEL: define {{[^@]+}}@select_and_phi
798; CHECK-SAME: (double returned [[B:%.*]]) #[[ATTR0]] {
799; CHECK-NEXT:  entry:
800; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[B]], 0.000000e+00
801; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
802; CHECK:       if.then:
803; CHECK-NEXT:    br label [[IF_END]]
804; CHECK:       if.end:
805; CHECK-NEXT:    ret double [[B]]
806;
807entry:
808  %cmp = fcmp ogt double %b, 0.000000e+00
809  br i1 %cmp, label %if.then, label %if.end
810
811if.then:                                          ; preds = %entry
812  br label %if.end
813
814if.end:                                           ; preds = %if.then, %entry
815  %phi = phi double [ %b, %if.then ], [ %b, %entry ]
816  %cmp1 = fcmp oeq double %b, 0.000000e+00
817  %sel = select i1 %cmp1, double %b, double %phi
818  ret double %sel
819}
820
821
822; TEST returned argument goes through recursion, select, and phi
823;
824; double recursion_select_and_phi(int a, double b) {
825;   double x = b;
826;   if (a-- > 0)
827;     x = recursion_select_and_phi(a, b);
828;   return b == 0? b : x;
829; }
830;
831define double @recursion_select_and_phi(i32 %a, double %b) #0 {
832; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
833; IS__TUNIT____-LABEL: define {{[^@]+}}@recursion_select_and_phi
834; IS__TUNIT____-SAME: (i32 [[A:%.*]], double returned [[B:%.*]]) #[[ATTR1]] {
835; IS__TUNIT____-NEXT:  entry:
836; IS__TUNIT____-NEXT:    [[DEC:%.*]] = add nsw i32 [[A]], -1
837; IS__TUNIT____-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], 0
838; IS__TUNIT____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
839; IS__TUNIT____:       if.then:
840; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call double @recursion_select_and_phi(i32 [[DEC]], double [[B]]) #[[ATTR10]]
841; IS__TUNIT____-NEXT:    br label [[IF_END]]
842; IS__TUNIT____:       if.end:
843; IS__TUNIT____-NEXT:    ret double [[B]]
844;
845; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
846; IS__CGSCC____-LABEL: define {{[^@]+}}@recursion_select_and_phi
847; IS__CGSCC____-SAME: (i32 [[A:%.*]], double returned [[B:%.*]]) #[[ATTR1]] {
848; IS__CGSCC____-NEXT:  entry:
849; IS__CGSCC____-NEXT:    [[DEC:%.*]] = add nsw i32 [[A]], -1
850; IS__CGSCC____-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], 0
851; IS__CGSCC____-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
852; IS__CGSCC____:       if.then:
853; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call double @recursion_select_and_phi(i32 [[DEC]], double [[B]]) #[[ATTR7]]
854; IS__CGSCC____-NEXT:    br label [[IF_END]]
855; IS__CGSCC____:       if.end:
856; IS__CGSCC____-NEXT:    ret double [[B]]
857;
858entry:
859  %dec = add nsw i32 %a, -1
860  %cmp = icmp sgt i32 %a, 0
861  br i1 %cmp, label %if.then, label %if.end
862
863if.then:                                          ; preds = %entry
864  %call = call double @recursion_select_and_phi(i32 %dec, double %b)
865  br label %if.end
866
867if.end:                                           ; preds = %if.then, %entry
868  %phi = phi double [ %call, %if.then ], [ %b, %entry ]
869  %cmp1 = fcmp oeq double %b, 0.000000e+00
870  %sel = select i1 %cmp1, double %b, double %phi
871  ret double %sel
872}
873
874
875; TEST returned argument goes through bitcasts
876;
877; double* bitcast(int* b) {
878;   return (double*)b;
879; }
880;
881define double* @bitcast(i32* %b) #0 {
882; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
883; CHECK-LABEL: define {{[^@]+}}@bitcast
884; CHECK-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR0]] {
885; CHECK-NEXT:  entry:
886; CHECK-NEXT:    [[BC0:%.*]] = bitcast i32* [[B]] to double*
887; CHECK-NEXT:    ret double* [[BC0]]
888;
889entry:
890  %bc0 = bitcast i32* %b to double*
891  ret double* %bc0
892}
893
894
895; TEST returned argument goes through select and phi interleaved with bitcasts
896;
897; double* bitcasts_select_and_phi(int* b) {
898;   double* x = b;
899;   if (b == 0)
900;     x = b;
901;   return b != 0 ? b : x;
902; }
903;
904define double* @bitcasts_select_and_phi(i32* %b) #0 {
905; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
906; CHECK-LABEL: define {{[^@]+}}@bitcasts_select_and_phi
907; CHECK-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] {
908; CHECK-NEXT:  entry:
909; CHECK-NEXT:    [[BC0:%.*]] = bitcast i32* [[B]] to double*
910; CHECK-NEXT:    [[CMP:%.*]] = icmp eq double* [[BC0]], null
911; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
912; CHECK:       if.then:
913; CHECK-NEXT:    [[BC1:%.*]] = bitcast i32* [[B]] to double*
914; CHECK-NEXT:    br label [[IF_END]]
915; CHECK:       if.end:
916; CHECK-NEXT:    [[PHI:%.*]] = phi double* [ [[BC1]], [[IF_THEN]] ], [ [[BC0]], [[ENTRY:%.*]] ]
917; CHECK-NEXT:    [[BC2:%.*]] = bitcast double* [[PHI]] to i8*
918; CHECK-NEXT:    [[BC3:%.*]] = bitcast i32* [[B]] to i8*
919; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne double* [[BC0]], null
920; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP2]], i8* [[BC2]], i8* [[BC3]]
921; CHECK-NEXT:    [[BC4:%.*]] = bitcast i8* [[SEL]] to double*
922; CHECK-NEXT:    ret double* [[BC4]]
923;
924entry:
925  %bc0 = bitcast i32* %b to double*
926  %cmp = icmp eq double* %bc0, null
927  br i1 %cmp, label %if.then, label %if.end
928
929if.then:                                          ; preds = %entry
930  %bc1 = bitcast i32* %b to double*
931  br label %if.end
932
933if.end:                                           ; preds = %if.then, %entry
934  %phi = phi double* [ %bc1, %if.then ], [ %bc0, %entry ]
935  %bc2 = bitcast double* %phi to i8*
936  %bc3 = bitcast i32* %b to i8*
937  %cmp2 = icmp ne double* %bc0, null
938  %sel = select i1 %cmp2, i8* %bc2, i8* %bc3
939  %bc4 = bitcast i8* %sel to double*
940  ret double* %bc4
941}
942
943
944; TEST return argument or argument or undef
945;
946; double* ret_arg_arg_undef(int* b) {
947;   if (b == 0)
948;     return (double*)b;
949;   if (b == 0)
950;     return (double*)b;
951;   /* return undef */
952; }
953;
954define double* @ret_arg_arg_undef(i32* %b) #0 {
955; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
956; CHECK-LABEL: define {{[^@]+}}@ret_arg_arg_undef
957; CHECK-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] {
958; CHECK-NEXT:  entry:
959; CHECK-NEXT:    [[BC0:%.*]] = bitcast i32* [[B]] to double*
960; CHECK-NEXT:    [[CMP:%.*]] = icmp eq double* [[BC0]], null
961; CHECK-NEXT:    br i1 [[CMP]], label [[RET_ARG0:%.*]], label [[IF_END:%.*]]
962; CHECK:       ret_arg0:
963; CHECK-NEXT:    [[BC1:%.*]] = bitcast i32* [[B]] to double*
964; CHECK-NEXT:    ret double* [[BC1]]
965; CHECK:       if.end:
966; CHECK-NEXT:    br i1 [[CMP]], label [[RET_ARG1:%.*]], label [[RET_UNDEF:%.*]]
967; CHECK:       ret_arg1:
968; CHECK-NEXT:    ret double* [[BC0]]
969; CHECK:       ret_undef:
970; CHECK-NEXT:    ret double* undef
971;
972entry:
973  %bc0 = bitcast i32* %b to double*
974  %cmp = icmp eq double* %bc0, null
975  br i1 %cmp, label %ret_arg0, label %if.end
976
977ret_arg0:
978  %bc1 = bitcast i32* %b to double*
979  ret double* %bc1
980
981if.end:
982  br i1 %cmp, label %ret_arg1, label %ret_undef
983
984ret_arg1:
985  ret double* %bc0
986
987ret_undef:
988  ret double *undef
989}
990
991
992; TEST return undef or argument or argument
993;
994; double* ret_undef_arg_arg(int* b) {
995;   if (b == 0)
996;     return (double*)b;
997;   if (b == 0)
998;     return (double*)b;
999;   /* return undef */
1000; }
1001;
1002define double* @ret_undef_arg_arg(i32* %b) #0 {
1003; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
1004; CHECK-LABEL: define {{[^@]+}}@ret_undef_arg_arg
1005; CHECK-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] {
1006; CHECK-NEXT:  entry:
1007; CHECK-NEXT:    [[BC0:%.*]] = bitcast i32* [[B]] to double*
1008; CHECK-NEXT:    [[CMP:%.*]] = icmp eq double* [[BC0]], null
1009; CHECK-NEXT:    br i1 [[CMP]], label [[RET_UNDEF:%.*]], label [[IF_END:%.*]]
1010; CHECK:       ret_undef:
1011; CHECK-NEXT:    ret double* undef
1012; CHECK:       if.end:
1013; CHECK-NEXT:    br i1 [[CMP]], label [[RET_ARG0:%.*]], label [[RET_ARG1:%.*]]
1014; CHECK:       ret_arg0:
1015; CHECK-NEXT:    ret double* [[BC0]]
1016; CHECK:       ret_arg1:
1017; CHECK-NEXT:    [[BC1:%.*]] = bitcast i32* [[B]] to double*
1018; CHECK-NEXT:    ret double* [[BC1]]
1019;
1020entry:
1021  %bc0 = bitcast i32* %b to double*
1022  %cmp = icmp eq double* %bc0, null
1023  br i1 %cmp, label %ret_undef, label %if.end
1024
1025ret_undef:
1026  ret double *undef
1027
1028if.end:
1029  br i1 %cmp, label %ret_arg0, label %ret_arg1
1030
1031ret_arg0:
1032  ret double* %bc0
1033
1034ret_arg1:
1035  %bc1 = bitcast i32* %b to double*
1036  ret double* %bc1
1037}
1038
1039
1040; TEST return undef or argument or undef
1041;
1042; double* ret_undef_arg_undef(int* b) {
1043;   if (b == 0)
1044;     /* return undef */
1045;   if (b == 0)
1046;     return (double*)b;
1047;   /* return undef */
1048; }
1049;
1050define double* @ret_undef_arg_undef(i32* %b) #0 {
1051; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
1052; CHECK-LABEL: define {{[^@]+}}@ret_undef_arg_undef
1053; CHECK-SAME: (i32* nofree readnone [[B:%.*]]) #[[ATTR0]] {
1054; CHECK-NEXT:  entry:
1055; CHECK-NEXT:    [[BC0:%.*]] = bitcast i32* [[B]] to double*
1056; CHECK-NEXT:    [[CMP:%.*]] = icmp eq double* [[BC0]], null
1057; CHECK-NEXT:    br i1 [[CMP]], label [[RET_UNDEF0:%.*]], label [[IF_END:%.*]]
1058; CHECK:       ret_undef0:
1059; CHECK-NEXT:    ret double* undef
1060; CHECK:       if.end:
1061; CHECK-NEXT:    br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNDEF1:%.*]]
1062; CHECK:       ret_arg:
1063; CHECK-NEXT:    ret double* [[BC0]]
1064; CHECK:       ret_undef1:
1065; CHECK-NEXT:    ret double* undef
1066;
1067entry:
1068  %bc0 = bitcast i32* %b to double*
1069  %cmp = icmp eq double* %bc0, null
1070  br i1 %cmp, label %ret_undef0, label %if.end
1071
1072ret_undef0:
1073  ret double *undef
1074
1075if.end:
1076  br i1 %cmp, label %ret_arg, label %ret_undef1
1077
1078ret_arg:
1079  ret double* %bc0
1080
1081ret_undef1:
1082  ret double *undef
1083}
1084
1085; TEST return argument or unknown call result
1086;
1087; int* ret_arg_or_unknown(int* b) {
1088;   if (b == 0)
1089;     return b;
1090;   return unknown();
1091; }
1092;
1093; Verify we do not assume b is returned
1094;
1095declare i32* @unknown(i32*)
1096
1097define i32* @ret_arg_or_unknown(i32* %b) #0 {
1098; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
1099; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_arg_or_unknown
1100; IS__TUNIT____-SAME: (i32* [[B:%.*]]) #[[ATTR5]] {
1101; IS__TUNIT____-NEXT:  entry:
1102; IS__TUNIT____-NEXT:    [[CMP:%.*]] = icmp eq i32* [[B]], null
1103; IS__TUNIT____-NEXT:    br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
1104; IS__TUNIT____:       ret_arg:
1105; IS__TUNIT____-NEXT:    ret i32* [[B]]
1106; IS__TUNIT____:       ret_unknown:
1107; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
1108; IS__TUNIT____-NEXT:    ret i32* [[CALL]]
1109;
1110; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
1111; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_arg_or_unknown
1112; IS__CGSCC____-SAME: (i32* [[B:%.*]]) #[[ATTR4]] {
1113; IS__CGSCC____-NEXT:  entry:
1114; IS__CGSCC____-NEXT:    [[CMP:%.*]] = icmp eq i32* [[B]], null
1115; IS__CGSCC____-NEXT:    br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
1116; IS__CGSCC____:       ret_arg:
1117; IS__CGSCC____-NEXT:    ret i32* [[B]]
1118; IS__CGSCC____:       ret_unknown:
1119; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
1120; IS__CGSCC____-NEXT:    ret i32* [[CALL]]
1121;
1122entry:
1123  %cmp = icmp eq i32* %b, null
1124  br i1 %cmp, label %ret_arg, label %ret_unknown
1125
1126ret_arg:
1127  ret i32* %b
1128
1129ret_unknown:
1130  %call = call i32* @unknown(i32* %b)
1131  ret i32* %call
1132}
1133
1134define i32* @ret_arg_or_unknown_through_phi(i32* %b) #0 {
1135; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
1136; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi
1137; IS__TUNIT____-SAME: (i32* [[B:%.*]]) #[[ATTR5]] {
1138; IS__TUNIT____-NEXT:  entry:
1139; IS__TUNIT____-NEXT:    [[CMP:%.*]] = icmp eq i32* [[B]], null
1140; IS__TUNIT____-NEXT:    br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
1141; IS__TUNIT____:       ret_arg:
1142; IS__TUNIT____-NEXT:    br label [[R:%.*]]
1143; IS__TUNIT____:       ret_unknown:
1144; IS__TUNIT____-NEXT:    [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
1145; IS__TUNIT____-NEXT:    br label [[R]]
1146; IS__TUNIT____:       r:
1147; IS__TUNIT____-NEXT:    [[PHI:%.*]] = phi i32* [ [[B]], [[RET_ARG]] ], [ [[CALL]], [[RET_UNKNOWN]] ]
1148; IS__TUNIT____-NEXT:    ret i32* [[PHI]]
1149;
1150; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
1151; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi
1152; IS__CGSCC____-SAME: (i32* [[B:%.*]]) #[[ATTR4]] {
1153; IS__CGSCC____-NEXT:  entry:
1154; IS__CGSCC____-NEXT:    [[CMP:%.*]] = icmp eq i32* [[B]], null
1155; IS__CGSCC____-NEXT:    br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
1156; IS__CGSCC____:       ret_arg:
1157; IS__CGSCC____-NEXT:    br label [[R:%.*]]
1158; IS__CGSCC____:       ret_unknown:
1159; IS__CGSCC____-NEXT:    [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
1160; IS__CGSCC____-NEXT:    br label [[R]]
1161; IS__CGSCC____:       r:
1162; IS__CGSCC____-NEXT:    [[PHI:%.*]] = phi i32* [ [[B]], [[RET_ARG]] ], [ [[CALL]], [[RET_UNKNOWN]] ]
1163; IS__CGSCC____-NEXT:    ret i32* [[PHI]]
1164;
1165entry:
1166  %cmp = icmp eq i32* %b, null
1167  br i1 %cmp, label %ret_arg, label %ret_unknown
1168
1169ret_arg:
1170  br label %r
1171
1172ret_unknown:
1173  %call = call i32* @unknown(i32* %b)
1174  br label %r
1175
1176r:
1177  %phi = phi i32* [ %b, %ret_arg ], [ %call, %ret_unknown ]
1178  ret i32* %phi
1179}
1180
1181; TEST inconsistent IR in dead code.
1182;
1183define i32 @deadblockcall1(i32 %A) #0 {
1184; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
1185; CHECK-LABEL: define {{[^@]+}}@deadblockcall1
1186; CHECK-SAME: (i32 returned [[A:%.*]]) #[[ATTR0]] {
1187; CHECK-NEXT:  entry:
1188; CHECK-NEXT:    ret i32 [[A]]
1189; CHECK:       unreachableblock:
1190; CHECK-NEXT:    unreachable
1191;
1192entry:
1193  ret i32 %A
1194unreachableblock:
1195  %B = call i32 @deadblockcall1(i32 %B)
1196  ret i32 %B
1197}
1198
1199declare i32 @deadblockcall_helper(i32 returned %A);
1200
1201define i32 @deadblockcall2(i32 %A) #0 {
1202; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
1203; CHECK-LABEL: define {{[^@]+}}@deadblockcall2
1204; CHECK-SAME: (i32 returned [[A:%.*]]) #[[ATTR0]] {
1205; CHECK-NEXT:  entry:
1206; CHECK-NEXT:    ret i32 [[A]]
1207; CHECK:       unreachableblock1:
1208; CHECK-NEXT:    unreachable
1209; CHECK:       unreachableblock2:
1210; CHECK-NEXT:    unreachable
1211;
1212entry:
1213  ret i32 %A
1214unreachableblock1:
1215  %B = call i32 @deadblockcall_helper(i32 %B)
1216  ret i32 %B
1217unreachableblock2:
1218  %C = call i32 @deadblockcall1(i32 %C)
1219  ret i32 %C
1220}
1221
1222define i32 @deadblockphi1(i32 %A) #0 {
1223; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
1224; CHECK-LABEL: define {{[^@]+}}@deadblockphi1
1225; CHECK-SAME: (i32 returned [[A:%.*]]) #[[ATTR0]] {
1226; CHECK-NEXT:  entry:
1227; CHECK-NEXT:    br label [[R:%.*]]
1228; CHECK:       unreachableblock1:
1229; CHECK-NEXT:    unreachable
1230; CHECK:       unreachableblock2:
1231; CHECK-NEXT:    unreachable
1232; CHECK:       r:
1233; CHECK-NEXT:    ret i32 [[A]]
1234;
1235entry:
1236  br label %r
1237unreachableblock1:
1238  %B = call i32 @deadblockcall_helper(i32 %B)
1239  ret i32 %B
1240unreachableblock2:
1241  %C = call i32 @deadblockcall1(i32 %C)
1242  br label %r
1243r:
1244  %PHI = phi i32 [%A, %entry], [%C, %unreachableblock2]
1245  ret i32 %PHI
1246}
1247
1248define i32 @deadblockphi2(i32 %A) #0 {
1249; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
1250; CHECK-LABEL: define {{[^@]+}}@deadblockphi2
1251; CHECK-SAME: (i32 returned [[A:%.*]]) #[[ATTR0]] {
1252; CHECK-NEXT:  entry:
1253; CHECK-NEXT:    br label [[R:%.*]]
1254; CHECK:       unreachableblock1:
1255; CHECK-NEXT:    unreachable
1256; CHECK:       unreachableblock2:
1257; CHECK-NEXT:    unreachable
1258; CHECK:       unreachableblock3:
1259; CHECK-NEXT:    unreachable
1260; CHECK:       r:
1261; CHECK-NEXT:    ret i32 [[A]]
1262;
1263entry:
1264  br label %r
1265unreachableblock1:
1266  %B = call i32 @deadblockcall_helper(i32 %B)
1267  br label %unreachableblock3
1268unreachableblock2:
1269  %C = call i32 @deadblockcall1(i32 %C)
1270  br label %unreachableblock3
1271unreachableblock3:
1272  %PHI1 = phi i32 [%B, %unreachableblock1], [%C, %unreachableblock2]
1273  br label %r
1274r:
1275  %PHI2 = phi i32 [%A, %entry], [%PHI1, %unreachableblock3]
1276  ret i32 %PHI2
1277}
1278
1279declare void @noreturn() noreturn;
1280
1281define i32 @deadblockphi3(i32 %A, i1 %c) #0 {
1282; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
1283; IS__TUNIT____-LABEL: define {{[^@]+}}@deadblockphi3
1284; IS__TUNIT____-SAME: (i32 returned [[A:%.*]], i1 [[C:%.*]]) #[[ATTR5]] {
1285; IS__TUNIT____-NEXT:  entry:
1286; IS__TUNIT____-NEXT:    br i1 [[C]], label [[R:%.*]], label [[UNREACHABLECALL:%.*]]
1287; IS__TUNIT____:       unreachablecall:
1288; IS__TUNIT____-NEXT:    call void @noreturn() #[[ATTR7:[0-9]+]]
1289; IS__TUNIT____-NEXT:    unreachable
1290; IS__TUNIT____:       unreachableblock2:
1291; IS__TUNIT____-NEXT:    unreachable
1292; IS__TUNIT____:       unreachableblock3:
1293; IS__TUNIT____-NEXT:    unreachable
1294; IS__TUNIT____:       r:
1295; IS__TUNIT____-NEXT:    ret i32 [[A]]
1296;
1297; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
1298; IS__CGSCC____-LABEL: define {{[^@]+}}@deadblockphi3
1299; IS__CGSCC____-SAME: (i32 returned [[A:%.*]], i1 [[C:%.*]]) #[[ATTR4]] {
1300; IS__CGSCC____-NEXT:  entry:
1301; IS__CGSCC____-NEXT:    br i1 [[C]], label [[R:%.*]], label [[UNREACHABLECALL:%.*]]
1302; IS__CGSCC____:       unreachablecall:
1303; IS__CGSCC____-NEXT:    call void @noreturn() #[[ATTR5:[0-9]+]]
1304; IS__CGSCC____-NEXT:    unreachable
1305; IS__CGSCC____:       unreachableblock2:
1306; IS__CGSCC____-NEXT:    unreachable
1307; IS__CGSCC____:       unreachableblock3:
1308; IS__CGSCC____-NEXT:    unreachable
1309; IS__CGSCC____:       r:
1310; IS__CGSCC____-NEXT:    ret i32 [[A]]
1311;
1312entry:
1313  br i1 %c, label %r, label %unreachablecall
1314unreachablecall:
1315  call void @noreturn();
1316  %B = call i32 @deadblockcall_helper(i32 0)
1317  br label %unreachableblock3
1318unreachableblock2:
1319  %C = call i32 @deadblockcall1(i32 %C)
1320  br label %unreachableblock3
1321unreachableblock3:
1322  %PHI1 = phi i32 [%B, %unreachablecall], [%C, %unreachableblock2]
1323  br label %r
1324r:
1325  %PHI2 = phi i32 [%A, %entry], [%PHI1, %unreachableblock3]
1326  ret i32 %PHI2
1327}
1328
1329define weak_odr i32 @non_exact_0() {
1330; CHECK-LABEL: define {{[^@]+}}@non_exact_0() {
1331; CHECK-NEXT:    ret i32 0
1332;
1333  ret i32 0
1334}
1335define weak_odr i32 @non_exact_1(i32 %a) {
1336; CHECK-LABEL: define {{[^@]+}}@non_exact_1
1337; CHECK-SAME: (i32 [[A:%.*]]) {
1338; CHECK-NEXT:    ret i32 [[A]]
1339;
1340  ret i32 %a
1341}
1342define weak_odr i32 @non_exact_2(i32 returned %a) {
1343; CHECK-LABEL: define {{[^@]+}}@non_exact_2
1344; CHECK-SAME: (i32 returned [[A:%.*]]) {
1345; CHECK-NEXT:    ret i32 [[A]]
1346;
1347  ret i32 %a
1348}
1349define weak_odr align 16 i32* @non_exact_3(i32* align 32 returned %a) {
1350; CHECK-LABEL: define {{[^@]+}}@non_exact_3
1351; CHECK-SAME: (i32* returned align 32 [[A:%.*]]) {
1352; CHECK-NEXT:    ret i32* [[A]]
1353;
1354  ret i32* %a
1355}
1356define weak_odr align 16 i32* @non_exact_4(i32* align 32 %a) {
1357; CHECK-LABEL: define {{[^@]+}}@non_exact_4
1358; CHECK-SAME: (i32* align 32 [[A:%.*]]) {
1359; CHECK-NEXT:    ret i32* [[A]]
1360;
1361  ret i32* %a
1362}
1363; We can use the alignment information of the weak function non_exact_3 argument
1364; because it was given to us and not derived.
1365; We can use the return information of the weak function non_exact_4.
1366; FIXME: %c2 and %c3 should be replaced but not %c0 or %c1!
1367define i32 @exact(i32* align 8 %a, i32* align 8 %b) {
1368; IS__TUNIT____: Function Attrs: norecurse
1369; IS__TUNIT____-LABEL: define {{[^@]+}}@exact
1370; IS__TUNIT____-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]]) #[[ATTR8:[0-9]+]] {
1371; IS__TUNIT____-NEXT:    [[C0:%.*]] = call i32 @non_exact_0()
1372; IS__TUNIT____-NEXT:    [[C1:%.*]] = call i32 @non_exact_1(i32 noundef 1)
1373; IS__TUNIT____-NEXT:    [[C2:%.*]] = call i32 @non_exact_2(i32 noundef 2)
1374; IS__TUNIT____-NEXT:    [[C3:%.*]] = call align 32 i32* @non_exact_3(i32* align 32 [[A]])
1375; IS__TUNIT____-NEXT:    [[C4:%.*]] = call align 16 i32* @non_exact_4(i32* align 32 [[B]])
1376; IS__TUNIT____-NEXT:    [[C3L:%.*]] = load i32, i32* [[A]], align 32
1377; IS__TUNIT____-NEXT:    [[C4L:%.*]] = load i32, i32* [[C4]], align 16
1378; IS__TUNIT____-NEXT:    [[ADD1:%.*]] = add i32 [[C0]], [[C1]]
1379; IS__TUNIT____-NEXT:    [[ADD2:%.*]] = add i32 [[ADD1]], 2
1380; IS__TUNIT____-NEXT:    [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]]
1381; IS__TUNIT____-NEXT:    [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]]
1382; IS__TUNIT____-NEXT:    ret i32 [[ADD4]]
1383;
1384; IS__CGSCC____-LABEL: define {{[^@]+}}@exact
1385; IS__CGSCC____-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]]) {
1386; IS__CGSCC____-NEXT:    [[C0:%.*]] = call i32 @non_exact_0()
1387; IS__CGSCC____-NEXT:    [[C1:%.*]] = call i32 @non_exact_1(i32 noundef 1)
1388; IS__CGSCC____-NEXT:    [[C2:%.*]] = call i32 @non_exact_2(i32 noundef 2)
1389; IS__CGSCC____-NEXT:    [[C3:%.*]] = call align 32 i32* @non_exact_3(i32* align 32 [[A]])
1390; IS__CGSCC____-NEXT:    [[C4:%.*]] = call align 16 i32* @non_exact_4(i32* align 32 [[B]])
1391; IS__CGSCC____-NEXT:    [[C3L:%.*]] = load i32, i32* [[C3]], align 32
1392; IS__CGSCC____-NEXT:    [[C4L:%.*]] = load i32, i32* [[C4]], align 16
1393; IS__CGSCC____-NEXT:    [[ADD1:%.*]] = add i32 [[C0]], [[C1]]
1394; IS__CGSCC____-NEXT:    [[ADD2:%.*]] = add i32 [[ADD1]], [[C2]]
1395; IS__CGSCC____-NEXT:    [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]]
1396; IS__CGSCC____-NEXT:    [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]]
1397; IS__CGSCC____-NEXT:    ret i32 [[ADD4]]
1398;
1399  %c0 = call i32 @non_exact_0()
1400  %c1 = call i32 @non_exact_1(i32 1)
1401  %c2 = call i32 @non_exact_2(i32 2)
1402  %c3 = call i32* @non_exact_3(i32* %a)
1403  %c4 = call i32* @non_exact_4(i32* %b)
1404  %c3l = load i32, i32* %c3
1405  %c4l = load i32, i32* %c4
1406  %add1 = add i32 %c0, %c1
1407  %add2 = add i32 %add1, %c2
1408  %add3 = add i32 %add2, %c3l
1409  %add4 = add i32 %add3, %c4l
1410  ret i32 %add4
1411}
1412
1413@G = external global i8
1414define i32* @ret_const() #0 {
1415; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
1416; CHECK-LABEL: define {{[^@]+}}@ret_const
1417; CHECK-SAME: () #[[ATTR0]] {
1418; CHECK-NEXT:    ret i32* bitcast (i8* @G to i32*)
1419;
1420  %bc = bitcast i8* @G to i32*
1421  ret i32* %bc
1422}
1423define i32* @use_const() #0 {
1424; IS__TUNIT____: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
1425; IS__TUNIT____-LABEL: define {{[^@]+}}@use_const
1426; IS__TUNIT____-SAME: () #[[ATTR0]] {
1427; IS__TUNIT____-NEXT:    ret i32* bitcast (i8* @G to i32*)
1428;
1429; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable
1430; IS__CGSCC____-LABEL: define {{[^@]+}}@use_const
1431; IS__CGSCC____-SAME: () #[[ATTR3]] {
1432; IS__CGSCC____-NEXT:    [[C:%.*]] = call noundef nonnull dereferenceable(1) i32* @ret_const() #[[ATTR11:[0-9]+]]
1433; IS__CGSCC____-NEXT:    ret i32* [[C]]
1434;
1435  %c = call i32* @ret_const()
1436  ret i32* %c
1437}
1438define i32* @dont_use_const() #0 {
1439; IS__TUNIT____: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable
1440; IS__TUNIT____-LABEL: define {{[^@]+}}@dont_use_const
1441; IS__TUNIT____-SAME: () #[[ATTR0]] {
1442; IS__TUNIT____-NEXT:    ret i32* bitcast (i8* @G to i32*)
1443;
1444; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable
1445; IS__CGSCC____-LABEL: define {{[^@]+}}@dont_use_const
1446; IS__CGSCC____-SAME: () #[[ATTR3]] {
1447; IS__CGSCC____-NEXT:    [[C:%.*]] = musttail call noundef nonnull dereferenceable(1) i32* @ret_const() #[[ATTR11]]
1448; IS__CGSCC____-NEXT:    ret i32* [[C]]
1449;
1450  %c = musttail call i32* @ret_const()
1451  ret i32* %c
1452}
1453
1454; UTC_ARGS: --disable
1455;
1456; Verify we do not derive constraints for @_Z3fooP1X as if it was returning `null`.
1457;
1458; CHEKC-NOT: noalias
1459; CHECK-NOT: align 536870912
1460
1461%struct.Y = type { %struct.X }
1462%struct.X = type { i32 (...)** }
1463
1464@_ZTI1X = external dso_local constant { i8*, i8* }, align 8
1465@_ZTI1Y = external dso_local constant { i8*, i8*, i8* }, align 8
1466
1467define internal i8* @_ZN1Y3barEv(%struct.Y* %this) align 2 {
1468entry:
1469  %0 = bitcast %struct.Y* %this to i8*
1470  ret i8* %0
1471}
1472
1473define dso_local i8* @_Z3fooP1X(%struct.X* %x) {
1474entry:
1475  %0 = icmp eq %struct.X* %x, null
1476  br i1 %0, label %dynamic_cast.null, label %dynamic_cast.notnull
1477
1478dynamic_cast.notnull:                             ; preds = %entry
1479  %1 = bitcast %struct.X* %x to i8*
1480  %2 = call i8* @__dynamic_cast(i8* %1, i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*), i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1Y to i8*), i64 0) #2
1481  %3 = bitcast i8* %2 to %struct.Y*
1482  br label %dynamic_cast.end
1483
1484dynamic_cast.null:                                ; preds = %entry
1485  br label %dynamic_cast.end
1486
1487dynamic_cast.end:                                 ; preds = %dynamic_cast.null, %dynamic_cast.notnull
1488  %QQ5 = phi %struct.Y* [ %3, %dynamic_cast.notnull ], [ null, %dynamic_cast.null ]
1489  %call = call i8* @_ZN1Y3barEv(%struct.Y* %QQ5)
1490  ret i8* %call
1491}
1492
1493declare dso_local i8* @__dynamic_cast(i8*, i8*, i8*, i64)
1494
1495; UTC_ARGS: --enable
1496
1497attributes #0 = { noinline nounwind uwtable }
1498;.
1499; IS__TUNIT____: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable }
1500; IS__TUNIT____: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable }
1501; IS__TUNIT____: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable }
1502; IS__TUNIT____: attributes #[[ATTR3]] = { argmemonly nofree noinline nosync nounwind readonly uwtable }
1503; IS__TUNIT____: attributes #[[ATTR4]] = { nofree noinline nosync nounwind readnone willreturn uwtable }
1504; IS__TUNIT____: attributes #[[ATTR5]] = { noinline nounwind uwtable }
1505; IS__TUNIT____: attributes #[[ATTR6]] = { noinline norecurse nounwind uwtable }
1506; IS__TUNIT____: attributes #[[ATTR7]] = { noreturn }
1507; IS__TUNIT____: attributes #[[ATTR8]] = { norecurse }
1508; IS__TUNIT____: attributes #[[ATTR9:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn }
1509; IS__TUNIT____: attributes #[[ATTR10]] = { nofree nosync nounwind readnone }
1510; IS__TUNIT____: attributes #[[ATTR11]] = { nofree nosync nounwind readonly }
1511; IS__TUNIT____: attributes #[[ATTR12]] = { nounwind }
1512; IS__TUNIT____: attributes #[[ATTR13:[0-9]+]] = { nounwind readnone }
1513;.
1514; IS__CGSCC____: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable }
1515; IS__CGSCC____: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable }
1516; IS__CGSCC____: attributes #[[ATTR2]] = { argmemonly nofree noinline nosync nounwind readonly uwtable }
1517; IS__CGSCC____: attributes #[[ATTR3]] = { nofree noinline nosync nounwind readnone willreturn uwtable }
1518; IS__CGSCC____: attributes #[[ATTR4]] = { noinline nounwind uwtable }
1519; IS__CGSCC____: attributes #[[ATTR5]] = { noreturn }
1520; IS__CGSCC____: attributes #[[ATTR6:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn }
1521; IS__CGSCC____: attributes #[[ATTR7]] = { nofree nosync nounwind readnone }
1522; IS__CGSCC____: attributes #[[ATTR8]] = { nounwind readnone }
1523; IS__CGSCC____: attributes #[[ATTR9]] = { nofree nosync nounwind readonly }
1524; IS__CGSCC____: attributes #[[ATTR10]] = { nounwind }
1525; IS__CGSCC____: attributes #[[ATTR11]] = { readnone willreturn }
1526;.
1527