xref: /llvm-project/llvm/test/Transforms/Attributor/value-simplify-local-remote.ll (revision 29441e4f5fa5f5c7709f7cf180815ba97f611297)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-annotate-decl-cs  -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
4
5; Most reduced from the OpenMC app running OpenMP offloading code, caused crashes before as we
6; mixed local and remote (=intra and inter procedural) values.
7
8target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
9
10%S = type { ptr }
11%S.2 = type { ptr, i64, i64 }
12%struct1 = type { %struct2 }
13%struct2 = type <{ ptr, i64, i64, i32, [4 x i8] }>
14
15define i64 @t1(ptr %first, ptr %first.addr, ptr %0) {
16; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
17; TUNIT-LABEL: define {{[^@]+}}@t1
18; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[FIRST:%.*]], ptr nofree readnone captures(none) [[FIRST_ADDR:%.*]], ptr nofree readnone captures(none) [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
19; TUNIT-NEXT:  entry:
20; TUNIT-NEXT:    [[FIRST_ADDR1:%.*]] = alloca ptr, i32 0, align 8
21; TUNIT-NEXT:    store ptr [[FIRST]], ptr [[FIRST]], align 8
22; TUNIT-NEXT:    br label [[IF_END:%.*]]
23; TUNIT:       if.end:
24; TUNIT-NEXT:    [[CALL:%.*]] = call ptr @foo.4(ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[FIRST]]) #[[ATTR3:[0-9]+]]
25; TUNIT-NEXT:    ret i64 0
26;
27; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: write)
28; CGSCC-LABEL: define {{[^@]+}}@t1
29; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[FIRST:%.*]], ptr nofree readnone captures(none) [[FIRST_ADDR:%.*]], ptr nofree readnone captures(none) [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
30; CGSCC-NEXT:  entry:
31; CGSCC-NEXT:    [[FIRST_ADDR1:%.*]] = alloca ptr, i32 0, align 8
32; CGSCC-NEXT:    store ptr [[FIRST]], ptr [[FIRST]], align 8
33; CGSCC-NEXT:    br label [[IF_END:%.*]]
34; CGSCC:       if.end:
35; CGSCC-NEXT:    [[CALL:%.*]] = call ptr @foo.4(ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[FIRST]]) #[[ATTR6:[0-9]+]]
36; CGSCC-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds double, ptr [[CALL]], i64 -1
37; CGSCC-NEXT:    ret i64 0
38;
39entry:
40  %first.addr1 = alloca ptr, i32 0, align 8
41  store ptr %first, ptr %first, align 8
42  br label %if.end
43
44if.end:                                           ; preds = %entry
45  %1 = load ptr, ptr %first, align 8
46  %call = call ptr @foo.4(ptr %first)
47  %add.ptr = getelementptr inbounds double, ptr %call, i64 -1
48  ret i64 0
49}
50
51define internal ptr @foo.4(ptr %__first) {
52; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
53; TUNIT-LABEL: define {{[^@]+}}@foo.4
54; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[__FIRST:%.*]]) #[[ATTR0]] {
55; TUNIT-NEXT:  entry:
56; TUNIT-NEXT:    [[__FIRST_ADDR:%.*]] = alloca ptr, i32 0, align 8
57; TUNIT-NEXT:    store ptr [[__FIRST]], ptr [[__FIRST]], align 8
58; TUNIT-NEXT:    ret ptr undef
59;
60; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: write)
61; CGSCC-LABEL: define {{[^@]+}}@foo.4
62; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[__FIRST:%.*]]) #[[ATTR0]] {
63; CGSCC-NEXT:  entry:
64; CGSCC-NEXT:    [[__FIRST_ADDR:%.*]] = alloca ptr, i32 0, align 8
65; CGSCC-NEXT:    store ptr [[__FIRST]], ptr [[__FIRST]], align 8
66; CGSCC-NEXT:    [[CALL1:%.*]] = call noalias noundef nonnull align 8 dereferenceable(8) ptr @bar(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[__FIRST]]) #[[ATTR7:[0-9]+]]
67; CGSCC-NEXT:    ret ptr [[CALL1]]
68;
69entry:
70  %__first.addr = alloca ptr, i32 0, align 8
71  store ptr %__first, ptr %__first, align 8
72  %0 = load ptr, ptr %__first, align 8
73  %call1 = call ptr @bar(ptr %__first)
74  ret ptr %call1
75}
76
77define internal ptr @bar(ptr %QQfirst) {
78; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
79; CGSCC-LABEL: define {{[^@]+}}@bar
80; CGSCC-SAME: (ptr noalias nofree noundef nonnull readnone returned align 8 dereferenceable(8) "no-capture-maybe-returned" [[QQFIRST:%.*]]) #[[ATTR1:[0-9]+]] {
81; CGSCC-NEXT:  entry:
82; CGSCC-NEXT:    [[QQFIRST_ADDR:%.*]] = alloca ptr, i32 0, align 8
83; CGSCC-NEXT:    store ptr [[QQFIRST]], ptr [[QQFIRST_ADDR]], align 8
84; CGSCC-NEXT:    br label [[WHILE_COND:%.*]]
85; CGSCC:       while.cond:
86; CGSCC-NEXT:    br label [[WHILE_END:%.*]]
87; CGSCC:       while.end:
88; CGSCC-NEXT:    ret ptr [[QQFIRST]]
89;
90entry:
91  %QQfirst.addr = alloca ptr, i32 0, align 8
92  store ptr %QQfirst, ptr %QQfirst.addr, align 8
93  br label %while.cond
94
95while.cond:                                       ; preds = %entry
96  br label %while.end
97
98while.end:                                        ; preds = %while.cond
99  %0 = load ptr, ptr %QQfirst.addr, align 8
100  ret ptr %0
101}
102
103define ptr @t2(ptr %this, ptr %this.addr, ptr %this1) {
104; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
105; TUNIT-LABEL: define {{[^@]+}}@t2
106; TUNIT-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree readnone captures(none) [[THIS_ADDR:%.*]], ptr nofree readnone captures(none) [[THIS1:%.*]]) #[[ATTR1:[0-9]+]] {
107; TUNIT-NEXT:  entry:
108; TUNIT-NEXT:    store ptr [[THIS]], ptr [[THIS]], align 8
109; TUNIT-NEXT:    [[CALL:%.*]] = call [[S:%.*]] @[[FOO_1:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR4:[0-9]+]]
110; TUNIT-NEXT:    [[TEST_RET:%.*]] = extractvalue [[S]] [[CALL]], 0
111; TUNIT-NEXT:    ret ptr [[TEST_RET]]
112;
113; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite)
114; CGSCC-LABEL: define {{[^@]+}}@t2
115; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree readnone captures(none) [[THIS_ADDR:%.*]], ptr nofree readnone captures(none) [[THIS1:%.*]]) #[[ATTR2:[0-9]+]] {
116; CGSCC-NEXT:  entry:
117; CGSCC-NEXT:    store ptr [[THIS]], ptr [[THIS]], align 8
118; CGSCC-NEXT:    [[CALL:%.*]] = call [[S:%.*]] @[[FOO_1:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8:[0-9]+]]
119; CGSCC-NEXT:    [[TEST_RET:%.*]] = extractvalue [[S]] [[CALL]], 0
120; CGSCC-NEXT:    ret ptr [[TEST_RET]]
121;
122entry:
123  store ptr %this, ptr %this, align 8
124  %this12 = load ptr, ptr %this, align 8
125  %call = call %S @foo.1(ptr %this)
126  %test.ret = extractvalue %S %call, 0
127  ret ptr %test.ret
128}
129
130define internal %S @foo.1(ptr %foo.this) {
131; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
132; TUNIT-LABEL: define {{[^@]+}}@foo.1
133; TUNIT-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[FOO_THIS:%.*]]) #[[ATTR1]] {
134; TUNIT-NEXT:  entry:
135; TUNIT-NEXT:    [[RETVAL:%.*]] = alloca [[S:%.*]], i32 0, align 8
136; TUNIT-NEXT:    store ptr [[FOO_THIS]], ptr [[FOO_THIS]], align 8
137; TUNIT-NEXT:    call void @bar.2(ptr noalias nofree noundef nonnull writeonly align 8 captures(none) [[RETVAL]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[FOO_THIS]]) #[[ATTR5:[0-9]+]]
138; TUNIT-NEXT:    [[FOO_RET:%.*]] = load [[S]], ptr [[RETVAL]], align 8
139; TUNIT-NEXT:    ret [[S]] [[FOO_RET]]
140;
141; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite)
142; CGSCC-LABEL: define {{[^@]+}}@foo.1
143; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[FOO_THIS:%.*]]) #[[ATTR2]] {
144; CGSCC-NEXT:  entry:
145; CGSCC-NEXT:    [[RETVAL:%.*]] = alloca [[S:%.*]], i32 0, align 8
146; CGSCC-NEXT:    store ptr [[FOO_THIS]], ptr [[FOO_THIS]], align 8
147; CGSCC-NEXT:    call void @bar.2(ptr noalias nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[RETVAL]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[FOO_THIS]]) #[[ATTR6]]
148; CGSCC-NEXT:    [[FOO_RET:%.*]] = load [[S]], ptr [[RETVAL]], align 8
149; CGSCC-NEXT:    ret [[S]] [[FOO_RET]]
150;
151entry:
152  %retval = alloca %S, i32 0, align 8
153  store ptr %foo.this, ptr %foo.this, align 8
154  call void @bar.2(ptr %retval, ptr %foo.this)
155  %foo.ret = load %S, ptr %retval, align 8
156  ret %S %foo.ret
157}
158
159define internal void @bar.2(ptr %bar.this, ptr %bar.data) {
160; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
161; TUNIT-LABEL: define {{[^@]+}}@bar.2
162; TUNIT-SAME: (ptr noalias nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[BAR_THIS:%.*]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_DATA:%.*]]) #[[ATTR0]] {
163; TUNIT-NEXT:  entry:
164; TUNIT-NEXT:    store ptr [[BAR_DATA]], ptr [[BAR_THIS]], align 8
165; TUNIT-NEXT:    call void @baz(ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[BAR_THIS]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_DATA]]) #[[ATTR5]]
166; TUNIT-NEXT:    ret void
167;
168; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: write)
169; CGSCC-LABEL: define {{[^@]+}}@bar.2
170; CGSCC-SAME: (ptr noalias nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[BAR_THIS:%.*]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_DATA:%.*]]) #[[ATTR0]] {
171; CGSCC-NEXT:  entry:
172; CGSCC-NEXT:    store ptr [[BAR_DATA]], ptr [[BAR_THIS]], align 8
173; CGSCC-NEXT:    call void @baz(ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[BAR_THIS]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAR_DATA]]) #[[ATTR6]]
174; CGSCC-NEXT:    ret void
175;
176entry:
177  store ptr %bar.data, ptr %bar.this, align 8
178  call void @baz(ptr %bar.this, ptr %bar.data)
179  ret void
180}
181
182define internal void @baz(ptr %baz.this, ptr %baz.data) {
183; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
184; TUNIT-LABEL: define {{[^@]+}}@baz
185; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[BAZ_THIS:%.*]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[BAZ_DATA:%.*]]) #[[ATTR0]] {
186; TUNIT-NEXT:  entry:
187; TUNIT-NEXT:    store ptr [[BAZ_DATA]], ptr [[BAZ_THIS]], align 8
188; TUNIT-NEXT:    ret void
189;
190; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
191; CGSCC-LABEL: define {{[^@]+}}@baz
192; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[BAZ_THIS:%.*]], ptr nofree writeonly [[BAZ_DATA:%.*]]) #[[ATTR3:[0-9]+]] {
193; CGSCC-NEXT:  entry:
194; CGSCC-NEXT:    store ptr [[BAZ_DATA]], ptr [[BAZ_THIS]], align 8
195; CGSCC-NEXT:    ret void
196;
197entry:
198  store ptr %baz.data, ptr %baz.this, align 8
199  ret void
200}
201
202define ptr @foo(ptr %this, ptr %this.addr, ptr %this1) {
203; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
204; TUNIT-LABEL: define {{[^@]+}}@foo
205; TUNIT-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree readnone captures(none) [[THIS_ADDR:%.*]], ptr nofree readnone captures(none) [[THIS1:%.*]]) #[[ATTR1]] {
206; TUNIT-NEXT:  entry:
207; TUNIT-NEXT:    store ptr [[THIS]], ptr [[THIS]], align 8
208; TUNIT-NEXT:    [[CALL:%.*]] = call [[S:%.*]] @[[BAR_5:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR4]]
209; TUNIT-NEXT:    [[FOO_RET:%.*]] = extractvalue [[S]] [[CALL]], 0
210; TUNIT-NEXT:    ret ptr [[FOO_RET]]
211;
212; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite)
213; CGSCC-LABEL: define {{[^@]+}}@foo
214; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree readnone captures(none) [[THIS_ADDR:%.*]], ptr nofree readnone captures(none) [[THIS1:%.*]]) #[[ATTR2]] {
215; CGSCC-NEXT:  entry:
216; CGSCC-NEXT:    store ptr [[THIS]], ptr [[THIS]], align 8
217; CGSCC-NEXT:    [[CALL:%.*]] = call [[S:%.*]] @[[BAR_5:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8]]
218; CGSCC-NEXT:    [[FOO_RET:%.*]] = extractvalue [[S]] [[CALL]], 0
219; CGSCC-NEXT:    ret ptr [[FOO_RET]]
220;
221entry:
222  store ptr %this, ptr %this, align 8
223  %this12 = load ptr, ptr %this, align 8
224  %call = call %S @bar.5(ptr %this)
225  %foo.ret = extractvalue %S %call, 0
226  ret ptr %foo.ret
227}
228
229define internal %S @bar.5(ptr %this) {
230; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
231; TUNIT-LABEL: define {{[^@]+}}@bar.5
232; TUNIT-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR1]] {
233; TUNIT-NEXT:  entry:
234; TUNIT-NEXT:    [[RETVAL:%.*]] = alloca [[S:%.*]], i32 0, align 8
235; TUNIT-NEXT:    store ptr [[THIS]], ptr [[THIS]], align 8
236; TUNIT-NEXT:    call void @baz.6(ptr noalias nofree noundef nonnull writeonly align 8 captures(none) [[RETVAL]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR4]]
237; TUNIT-NEXT:    [[BAR_RET:%.*]] = load [[S]], ptr [[RETVAL]], align 8
238; TUNIT-NEXT:    ret [[S]] [[BAR_RET]]
239;
240; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite)
241; CGSCC-LABEL: define {{[^@]+}}@bar.5
242; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR2]] {
243; CGSCC-NEXT:  entry:
244; CGSCC-NEXT:    [[RETVAL:%.*]] = alloca [[S:%.*]], i32 0, align 8
245; CGSCC-NEXT:    store ptr [[THIS]], ptr [[THIS]], align 8
246; CGSCC-NEXT:    call void @baz.6(ptr noalias nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[RETVAL]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR9:[0-9]+]]
247; CGSCC-NEXT:    [[BAR_RET:%.*]] = load [[S]], ptr [[RETVAL]], align 8
248; CGSCC-NEXT:    ret [[S]] [[BAR_RET]]
249;
250entry:
251  %retval = alloca %S, i32 0, align 8
252  store ptr %this, ptr %this, align 8
253  %0 = load ptr, ptr %this, align 8
254  call void @baz.6(ptr %retval, ptr %this)
255  %bar.ret = load %S, ptr %retval, align 8
256  ret %S %bar.ret
257}
258
259define internal void @baz.6(ptr %this, ptr %data) {
260; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
261; TUNIT-LABEL: define {{[^@]+}}@baz.6
262; TUNIT-SAME: (ptr noalias nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[THIS:%.*]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[DATA:%.*]]) #[[ATTR1]] {
263; TUNIT-NEXT:  entry:
264; TUNIT-NEXT:    store ptr [[DATA]], ptr [[THIS]], align 8
265; TUNIT-NEXT:    call void @boom(ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[THIS]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[DATA]]) #[[ATTR4]]
266; TUNIT-NEXT:    ret void
267;
268; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite)
269; CGSCC-LABEL: define {{[^@]+}}@baz.6
270; CGSCC-SAME: (ptr noalias nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[THIS:%.*]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[DATA:%.*]]) #[[ATTR2]] {
271; CGSCC-NEXT:  entry:
272; CGSCC-NEXT:    store ptr [[DATA]], ptr [[THIS]], align 8
273; CGSCC-NEXT:    call void @boom(ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[THIS]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[DATA]]) #[[ATTR9]]
274; CGSCC-NEXT:    ret void
275;
276entry:
277  store ptr %data, ptr %this, align 8
278  call void @boom(ptr %this, ptr %data)
279  ret void
280}
281
282define internal void @boom(ptr %this, ptr %data) {
283; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
284; TUNIT-LABEL: define {{[^@]+}}@boom
285; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[THIS:%.*]], ptr nofree noundef nonnull align 8 dereferenceable(8) [[DATA:%.*]]) #[[ATTR1]] {
286; TUNIT-NEXT:  entry:
287; TUNIT-NEXT:    [[DATA_ADDR:%.*]] = alloca ptr, i32 0, align 8
288; TUNIT-NEXT:    store ptr [[DATA]], ptr [[DATA_ADDR]], align 8
289; TUNIT-NEXT:    [[V:%.*]] = load ptr, ptr [[DATA_ADDR]], align 8
290; TUNIT-NEXT:    store ptr [[V]], ptr [[THIS]], align 8
291; TUNIT-NEXT:    ret void
292;
293; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
294; CGSCC-LABEL: define {{[^@]+}}@boom
295; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[THIS:%.*]], ptr nofree [[DATA:%.*]]) #[[ATTR4:[0-9]+]] {
296; CGSCC-NEXT:  entry:
297; CGSCC-NEXT:    [[DATA_ADDR:%.*]] = alloca ptr, i32 0, align 8
298; CGSCC-NEXT:    store ptr [[DATA]], ptr [[DATA_ADDR]], align 8
299; CGSCC-NEXT:    store ptr [[DATA]], ptr [[THIS]], align 8
300; CGSCC-NEXT:    ret void
301;
302entry:
303  %data.addr = alloca ptr, i32 0, align 8
304  store ptr %data, ptr %data.addr, align 8
305  %v = load ptr, ptr %data.addr, align 8
306  store ptr %v, ptr %this, align 8
307  ret void
308}
309
310define weak_odr void @t3() {
311; CHECK-LABEL: define {{[^@]+}}@t3() {
312; CHECK-NEXT:  entry:
313; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @__kmpc_target_init(ptr noundef align 4294967296 null)
314; CHECK-NEXT:    br label [[USER_CODE_ENTRY:%.*]]
315; CHECK:       user_code.entry:
316; CHECK-NEXT:    br label [[FOR_COND:%.*]]
317; CHECK:       for.cond:
318; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
319; CHECK:       for.body:
320; CHECK-NEXT:    [[CALL4:%.*]] = call [[S_2:%.*]] @[[T3_HELPER:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]]()
321; CHECK-NEXT:    ret void
322;
323entry:
324  %0 = call i32 @__kmpc_target_init(ptr null)
325  br label %user_code.entry
326
327user_code.entry:                                  ; preds = %entry
328  br label %for.cond
329
330for.cond:                                         ; preds = %user_code.entry
331  br label %for.body
332
333for.body:                                         ; preds = %for.cond
334  %call4 = call %S.2 @t3.helper()
335  ret void
336}
337
338declare i32 @__kmpc_target_init(ptr)
339
340define %S.2 @t3.helper() {
341; CHECK-LABEL: define {{[^@]+}}@t3.helper() {
342; CHECK-NEXT:  entry:
343; CHECK-NEXT:    [[RETVAL:%.*]] = alloca [[S_2:%.*]], align 8
344; CHECK-NEXT:    call void @ext1(ptr noundef nonnull align 8 dereferenceable(24) [[RETVAL]])
345; CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load ptr, ptr [[RETVAL]], align 8
346; CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [[S_2]] poison, ptr [[DOTFCA_0_LOAD]], 0
347; CHECK-NEXT:    [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [[S_2]], ptr [[RETVAL]], i32 0, i32 1
348; CHECK-NEXT:    [[DOTFCA_1_LOAD:%.*]] = load i64, ptr [[DOTFCA_1_GEP]], align 8
349; CHECK-NEXT:    [[DOTFCA_1_INSERT:%.*]] = insertvalue [[S_2]] [[DOTFCA_0_INSERT]], i64 [[DOTFCA_1_LOAD]], 1
350; CHECK-NEXT:    [[DOTFCA_2_GEP:%.*]] = getelementptr inbounds [[S_2]], ptr [[RETVAL]], i32 0, i32 2
351; CHECK-NEXT:    [[DOTFCA_2_LOAD:%.*]] = load i64, ptr [[DOTFCA_2_GEP]], align 8
352; CHECK-NEXT:    [[DOTFCA_2_INSERT:%.*]] = insertvalue [[S_2]] [[DOTFCA_1_INSERT]], i64 [[DOTFCA_2_LOAD]], 2
353; CHECK-NEXT:    ret [[S_2]] zeroinitializer
354;
355entry:
356  %retval = alloca %S.2, align 8
357  call void @ext1(ptr %retval)
358  %.fca.0.gep = getelementptr inbounds %S.2, ptr %retval, i32 0, i32 0
359  %.fca.0.load = load ptr, ptr %.fca.0.gep, align 8
360  %.fca.0.insert = insertvalue %S.2 poison, ptr %.fca.0.load, 0
361  %.fca.1.gep = getelementptr inbounds %S.2, ptr %retval, i32 0, i32 1
362  %.fca.1.load = load i64, ptr %.fca.1.gep, align 8
363  %.fca.1.insert = insertvalue %S.2 %.fca.0.insert, i64 %.fca.1.load, 1
364  %.fca.2.gep = getelementptr inbounds %S.2, ptr %retval, i32 0, i32 2
365  %.fca.2.load = load i64, ptr %.fca.2.gep, align 8
366  %.fca.2.insert = insertvalue %S.2 %.fca.1.insert, i64 %.fca.2.load, 2
367  ret %S.2 zeroinitializer
368}
369
370declare void @ext1(ptr)
371
372; Taken from https://github.com/llvm/llvm-project/issues/54981
373define dso_local void @spam() {
374; TUNIT: Function Attrs: nofree norecurse noreturn nosync nounwind memory(none)
375; TUNIT-LABEL: define {{[^@]+}}@spam
376; TUNIT-SAME: () #[[ATTR2:[0-9]+]] {
377; TUNIT-NEXT:  bb:
378; TUNIT-NEXT:    [[TMP:%.*]] = alloca i32, align 4
379; TUNIT-NEXT:    [[X:%.*]] = fptosi float undef to i32
380; TUNIT-NEXT:    store i32 [[X]], ptr [[TMP]], align 4
381; TUNIT-NEXT:    br label [[BB16:%.*]]
382; TUNIT:       bb16:
383; TUNIT-NEXT:    [[TMP18:%.*]] = icmp eq i32 [[X]], 0
384; TUNIT-NEXT:    br i1 [[TMP18]], label [[BB35:%.*]], label [[BB19:%.*]]
385; TUNIT:       bb19:
386; TUNIT-NEXT:    br label [[BB23:%.*]]
387; TUNIT:       bb23:
388; TUNIT-NEXT:    br label [[BB25:%.*]]
389; TUNIT:       bb25:
390; TUNIT-NEXT:    unreachable
391; TUNIT:       bb28:
392; TUNIT-NEXT:    unreachable
393; TUNIT:       bb34:
394; TUNIT-NEXT:    unreachable
395; TUNIT:       bb35:
396; TUNIT-NEXT:    unreachable
397;
398; CGSCC: Function Attrs: nofree norecurse noreturn nosync nounwind memory(none)
399; CGSCC-LABEL: define {{[^@]+}}@spam
400; CGSCC-SAME: () #[[ATTR5:[0-9]+]] {
401; CGSCC-NEXT:  bb:
402; CGSCC-NEXT:    [[TMP:%.*]] = alloca i32, align 4
403; CGSCC-NEXT:    [[X:%.*]] = fptosi float undef to i32
404; CGSCC-NEXT:    store i32 [[X]], ptr [[TMP]], align 4
405; CGSCC-NEXT:    br label [[BB16:%.*]]
406; CGSCC:       bb16:
407; CGSCC-NEXT:    [[TMP18:%.*]] = icmp eq i32 [[X]], 0
408; CGSCC-NEXT:    br i1 [[TMP18]], label [[BB35:%.*]], label [[BB19:%.*]]
409; CGSCC:       bb19:
410; CGSCC-NEXT:    br label [[BB23:%.*]]
411; CGSCC:       bb23:
412; CGSCC-NEXT:    br label [[BB25:%.*]]
413; CGSCC:       bb25:
414; CGSCC-NEXT:    unreachable
415; CGSCC:       bb28:
416; CGSCC-NEXT:    unreachable
417; CGSCC:       bb34:
418; CGSCC-NEXT:    unreachable
419; CGSCC:       bb35:
420; CGSCC-NEXT:    unreachable
421;
422bb:
423  %tmp = alloca i32, align 4
424  %tmp12 = getelementptr inbounds i32, ptr %tmp, i64 0
425  %tmp15 = getelementptr inbounds i32, ptr %tmp, i64 0
426  %x = fptosi float undef to i32
427  store i32 %x, ptr %tmp15, align 4
428  br label %bb16
429
430bb16:                                             ; preds = %bb
431  %tmp17 = load i32, ptr %tmp12, align 4
432  %tmp18 = icmp eq i32 %tmp17, 0
433  br i1 %tmp18, label %bb35, label %bb19
434
435bb19:                                             ; preds = %bb16
436  %y = getelementptr inbounds i32, ptr %tmp, i64 0
437  %tmp20 = bitcast ptr %y to ptr
438  %tmp21 = load float, ptr %tmp20, align 4
439  %tmp22 = fadd fast float %tmp21, 0.000000e+00
440  br label %bb23
441
442bb23:                                             ; preds = %bb34, %bb19
443  %tmp24 = phi <2 x float> [ undef, %bb19 ], [ %tmp26, %bb34 ]
444  br label %bb25
445
446bb25:                                             ; preds = %bb28, %bb23
447  %tmp26 = phi <2 x float> [ %tmp30, %bb28 ], [ %tmp24, %bb23 ]
448  %tmp27 = icmp ult i32 undef, 8
449  br i1 %tmp27, label %bb28, label %bb34
450
451bb28:                                             ; preds = %bb25
452  %tmp29 = insertelement <2 x float> %tmp26, float undef, i32 0
453  %tmp30 = insertelement <2 x float> %tmp29, float %tmp22, i32 1
454  br label %bb25
455
456bb34:                                             ; preds = %bb25
457  br label %bb23
458
459bb35:                                             ; preds = %bb16
460  unreachable
461}
462
463define double @t4(ptr %this, ptr %this.addr, ptr %this1) {
464; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
465; TUNIT-LABEL: define {{[^@]+}}@t4
466; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree readnone captures(none) [[THIS_ADDR:%.*]], ptr nofree readnone captures(none) [[THIS1:%.*]]) #[[ATTR0]] {
467; TUNIT-NEXT:  entry:
468; TUNIT-NEXT:    [[THIS_ADDR1:%.*]] = alloca ptr, i32 0, align 8
469; TUNIT-NEXT:    store ptr [[THIS]], ptr [[THIS]], align 8
470; TUNIT-NEXT:    [[CALL:%.*]] = call [[S:%.*]] @[[T4A:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]]) #[[ATTR5]]
471; TUNIT-NEXT:    ret double 0.000000e+00
472;
473; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite)
474; CGSCC-LABEL: define {{[^@]+}}@t4
475; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]], ptr nofree readnone captures(none) [[THIS_ADDR:%.*]], ptr nofree readnone captures(none) [[THIS1:%.*]]) #[[ATTR2]] {
476; CGSCC-NEXT:  entry:
477; CGSCC-NEXT:    [[THIS_ADDR1:%.*]] = alloca ptr, i32 0, align 8
478; CGSCC-NEXT:    store ptr [[THIS]], ptr [[THIS]], align 8
479; CGSCC-NEXT:    [[CALL:%.*]] = call [[S:%.*]] @[[T4A:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS]]) #[[ATTR8]]
480; CGSCC-NEXT:    [[TMP0:%.*]] = extractvalue [[S]] [[CALL]], 0
481; CGSCC-NEXT:    ret double 0.000000e+00
482;
483entry:
484  %this.addr1 = alloca ptr, i32 0, align 8
485  store ptr %this, ptr %this, align 8
486  %this12 = load ptr, ptr %this, align 8
487  %call = call %S @t4a(ptr %this)
488  %0 = extractvalue %S %call, 0
489  ret double 0.000000e+00
490}
491
492define internal %S @t4a(ptr %this) {
493; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
494; TUNIT-LABEL: define {{[^@]+}}@t4a
495; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR0]] {
496; TUNIT-NEXT:  entry:
497; TUNIT-NEXT:    [[RETVAL:%.*]] = alloca [[S:%.*]], i32 0, align 8
498; TUNIT-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, i32 0, align 8
499; TUNIT-NEXT:    store ptr [[THIS]], ptr [[THIS]], align 8
500; TUNIT-NEXT:    call void @t4b(ptr noalias nofree noundef nonnull writeonly align 8 captures(none) [[RETVAL]]) #[[ATTR5]]
501; TUNIT-NEXT:    ret [[S]] undef
502;
503; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite)
504; CGSCC-LABEL: define {{[^@]+}}@t4a
505; CGSCC-SAME: (ptr nofree noundef nonnull align 8 dereferenceable(8) [[THIS:%.*]]) #[[ATTR2]] {
506; CGSCC-NEXT:  entry:
507; CGSCC-NEXT:    [[RETVAL:%.*]] = alloca [[S:%.*]], i32 0, align 8
508; CGSCC-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, i32 0, align 8
509; CGSCC-NEXT:    store ptr [[THIS]], ptr [[THIS]], align 8
510; CGSCC-NEXT:    call void @t4b(ptr noalias nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[RETVAL]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[THIS]]) #[[ATTR6]]
511; CGSCC-NEXT:    [[TMP0:%.*]] = load [[S]], ptr [[RETVAL]], align 8
512; CGSCC-NEXT:    ret [[S]] [[TMP0]]
513;
514entry:
515  %retval = alloca %S, i32 0, align 8
516  %this.addr = alloca ptr, i32 0, align 8
517  store ptr %this, ptr %this, align 8
518  %this1 = load ptr, ptr %this, align 8
519  %buffer_ = getelementptr inbounds %struct1, ptr %this1, i32 0, i32 0
520  %data_ = getelementptr inbounds %struct2, ptr %buffer_, i32 0, i32 0
521  %0 = load ptr, ptr %this, align 8
522  call void @t4b(ptr %retval, ptr %this)
523  %1 = load %S, ptr %retval, align 8
524  ret %S %1
525}
526
527define internal void @t4b(ptr %this, ptr %data) {
528; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
529; TUNIT-LABEL: define {{[^@]+}}@t4b
530; TUNIT-SAME: (ptr noalias nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[THIS:%.*]]) #[[ATTR0]] {
531; TUNIT-NEXT:  entry:
532; TUNIT-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, i32 0, align 8
533; TUNIT-NEXT:    [[DATA_ADDR:%.*]] = alloca ptr, i32 0, align 8
534; TUNIT-NEXT:    call void @t4c(ptr noalias nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[THIS]]) #[[ATTR5]]
535; TUNIT-NEXT:    ret void
536;
537; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: write)
538; CGSCC-LABEL: define {{[^@]+}}@t4b
539; CGSCC-SAME: (ptr noalias nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[THIS:%.*]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[DATA:%.*]]) #[[ATTR0]] {
540; CGSCC-NEXT:  entry:
541; CGSCC-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, i32 0, align 8
542; CGSCC-NEXT:    [[DATA_ADDR:%.*]] = alloca ptr, i32 0, align 8
543; CGSCC-NEXT:    store ptr [[DATA]], ptr [[THIS]], align 8
544; CGSCC-NEXT:    call void @t4c(ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[THIS]], ptr nofree noundef nonnull writeonly align 8 dereferenceable(8) [[DATA]]) #[[ATTR6]]
545; CGSCC-NEXT:    ret void
546;
547entry:
548  %this.addr = alloca ptr, i32 0, align 8
549  %data.addr = alloca ptr, i32 0, align 8
550  store ptr %this, ptr %this.addr, align 8
551  store ptr %data, ptr %this, align 8
552  %this1 = load ptr, ptr %this, align 8
553  %0 = load ptr, ptr %this, align 8
554  call void @t4c(ptr %this, ptr %data)
555  ret void
556}
557
558define internal void @t4c(ptr %this, ptr %data) {
559; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
560; TUNIT-LABEL: define {{[^@]+}}@t4c
561; TUNIT-SAME: (ptr noalias nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[THIS:%.*]]) #[[ATTR0]] {
562; TUNIT-NEXT:  entry:
563; TUNIT-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, i32 0, align 8
564; TUNIT-NEXT:    [[DATA_ADDR:%.*]] = alloca ptr, i32 0, align 8
565; TUNIT-NEXT:    ret void
566;
567; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
568; CGSCC-LABEL: define {{[^@]+}}@t4c
569; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[THIS:%.*]], ptr nofree writeonly [[DATA:%.*]]) #[[ATTR3]] {
570; CGSCC-NEXT:  entry:
571; CGSCC-NEXT:    [[THIS_ADDR:%.*]] = alloca ptr, i32 0, align 8
572; CGSCC-NEXT:    [[DATA_ADDR:%.*]] = alloca ptr, i32 0, align 8
573; CGSCC-NEXT:    store ptr [[DATA]], ptr [[THIS]], align 8
574; CGSCC-NEXT:    store ptr [[DATA]], ptr [[THIS]], align 8
575; CGSCC-NEXT:    ret void
576;
577entry:
578  %this.addr = alloca ptr, i32 0, align 8
579  %data.addr = alloca ptr, i32 0, align 8
580  store ptr %this, ptr %this.addr, align 8
581  store ptr %data, ptr %this, align 8
582  %this1 = load ptr, ptr %this, align 8
583  %data_ = getelementptr inbounds %S, ptr %this1, i32 0, i32 0
584  %0 = load ptr, ptr %this, align 8
585  store ptr %data, ptr %this, align 8
586  ret void
587}
588
589!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7}
590
591!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 11, i32 5]}
592!1 = !{i32 1, !"wchar_size", i32 4}
593!2 = !{i32 7, !"openmp", i32 50}
594!3 = !{i32 7, !"openmp-device", i32 50}
595!4 = !{i32 8, !"PIC Level", i32 2}
596!5 = !{i32 7, !"frame-pointer", i32 2}
597!6 = !{i32 7, !"Dwarf Version", i32 2}
598!7 = !{i32 2, !"Debug Info Version", i32 3}
599;.
600; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
601; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) }
602; TUNIT: attributes #[[ATTR2]] = { nofree norecurse noreturn nosync nounwind memory(none) }
603; TUNIT: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn memory(write) }
604; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn }
605; TUNIT: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn memory(write) }
606;.
607; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: write) }
608; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
609; CGSCC: attributes #[[ATTR2]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) }
610; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
611; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) }
612; CGSCC: attributes #[[ATTR5]] = { nofree norecurse noreturn nosync nounwind memory(none) }
613; CGSCC: attributes #[[ATTR6]] = { nofree nounwind willreturn memory(write) }
614; CGSCC: attributes #[[ATTR7]] = { nofree nosync willreturn }
615; CGSCC: attributes #[[ATTR8]] = { nofree nounwind willreturn }
616; CGSCC: attributes #[[ATTR9]] = { nofree nounwind willreturn memory(readwrite) }
617;.
618; TUNIT: [[META0:![0-9]+]] = !{i32 2, !"SDK Version", [2 x i32] [i32 11, i32 5]}
619; TUNIT: [[META1:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
620; TUNIT: [[META2:![0-9]+]] = !{i32 7, !"openmp", i32 50}
621; TUNIT: [[META3:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
622; TUNIT: [[META4:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
623; TUNIT: [[META5:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
624; TUNIT: [[META6:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 2}
625; TUNIT: [[META7:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}
626;.
627; CGSCC: [[META0:![0-9]+]] = !{i32 2, !"SDK Version", [2 x i32] [i32 11, i32 5]}
628; CGSCC: [[META1:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
629; CGSCC: [[META2:![0-9]+]] = !{i32 7, !"openmp", i32 50}
630; CGSCC: [[META3:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
631; CGSCC: [[META4:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
632; CGSCC: [[META5:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
633; CGSCC: [[META6:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 2}
634; CGSCC: [[META7:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}
635;.
636