xref: /llvm-project/llvm/test/Transforms/Attributor/value-simplify-gpu.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
5target triple = "amdgcn-amd-amdhsa"
6
7%struct.ident_t = type { i32, i32, i32, i32, ptr }
8@ReachableKernel = internal addrspace(3) global i32 3, align 4
9@UnreachableKernel = internal addrspace(3) global i32 42, align 4
10@ReachableKernelAS0 = internal global i32 7, align 4
11@AS3OneKernelAtATime = internal addrspace(3) global i32 42, align 4
12
13;.
14; CHECK: @ReachableKernel = internal addrspace(3) global i32 3, align 4
15; CHECK: @UnreachableKernel = internal addrspace(3) global i32 42, align 4
16; CHECK: @ReachableKernelAS0 = internal global i32 7, align 4
17; CHECK: @AS3OneKernelAtATime = internal addrspace(3) global i32 42, align 4
18; CHECK: @ReachableNonKernel = internal addrspace(3) global i32 0, align 4
19; CHECK: @UnreachableNonKernel = internal addrspace(3) global i32 0, align 4
20;.
21define dso_local void @kernel(i32 %C) norecurse "kernel" {
22; TUNIT: Function Attrs: norecurse nosync nounwind
23; TUNIT-LABEL: define {{[^@]+}}@kernel
24; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
25; TUNIT-NEXT:  entry:
26; TUNIT-NEXT:    call void @level1Kernel(i32 [[C]]) #[[ATTR1:[0-9]+]]
27; TUNIT-NEXT:    ret void
28;
29; CGSCC: Function Attrs: norecurse nosync nounwind
30; CGSCC-LABEL: define {{[^@]+}}@kernel
31; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
32; CGSCC-NEXT:  entry:
33; CGSCC-NEXT:    call void @level1Kernel(i32 [[C]]) #[[ATTR4:[0-9]+]]
34; CGSCC-NEXT:    ret void
35;
36entry:
37  call void @level1Kernel(i32 %C)
38  ret void
39}
40
41define internal void @level1Kernel(i32 %C) {
42; TUNIT: Function Attrs: norecurse nosync nounwind
43; TUNIT-LABEL: define {{[^@]+}}@level1Kernel
44; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
45; TUNIT-NEXT:  entry:
46; TUNIT-NEXT:    call void @level2Kernelall_early() #[[ATTR4:[0-9]+]]
47; TUNIT-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0
48; TUNIT-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
49; TUNIT:       if.then:
50; TUNIT-NEXT:    call void @level2Kernela() #[[ATTR5:[0-9]+]]
51; TUNIT-NEXT:    br label [[IF_END:%.*]]
52; TUNIT:       if.else:
53; TUNIT-NEXT:    call void @level2Kernelb() #[[ATTR5]]
54; TUNIT-NEXT:    br label [[IF_END]]
55; TUNIT:       if.end:
56; TUNIT-NEXT:    call void @level2Kernelall_late() #[[ATTR6:[0-9]+]]
57; TUNIT-NEXT:    ret void
58;
59; CGSCC: Function Attrs: norecurse nosync nounwind
60; CGSCC-LABEL: define {{[^@]+}}@level1Kernel
61; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR1:[0-9]+]] {
62; CGSCC-NEXT:  entry:
63; CGSCC-NEXT:    call void @level2Kernelall_early() #[[ATTR5:[0-9]+]]
64; CGSCC-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0
65; CGSCC-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
66; CGSCC:       if.then:
67; CGSCC-NEXT:    call void @level2Kernela() #[[ATTR4]]
68; CGSCC-NEXT:    br label [[IF_END:%.*]]
69; CGSCC:       if.else:
70; CGSCC-NEXT:    call void @level2Kernelb() #[[ATTR4]]
71; CGSCC-NEXT:    br label [[IF_END]]
72; CGSCC:       if.end:
73; CGSCC-NEXT:    call void @level2Kernelall_late() #[[ATTR6:[0-9]+]]
74; CGSCC-NEXT:    ret void
75;
76entry:
77  call void @level2Kernelall_early()
78  %tobool = icmp ne i32 %C, 0
79  br i1 %tobool, label %if.then, label %if.else
80
81if.then:                                          ; preds = %entry
82  call void @level2Kernela()
83  br label %if.end
84
85if.else:                                          ; preds = %entry
86  call void @level2Kernelb()
87  br label %if.end
88
89if.end:                                           ; preds = %if.else, %if.then
90  call void @level2Kernelall_late()
91  ret void
92}
93
94define internal void @level2Kernelall_early() {
95; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
96; CHECK-LABEL: define {{[^@]+}}@level2Kernelall_early
97; CHECK-SAME: () #[[ATTR2:[0-9]+]] {
98; CHECK-NEXT:  entry:
99; CHECK-NEXT:    store i32 1, ptr @ReachableKernelAS0, align 4
100; CHECK-NEXT:    store i32 1, ptr addrspace(3) @ReachableKernel, align 4
101; CHECK-NEXT:    ret void
102;
103entry:
104  store i32 1, ptr @ReachableKernelAS0, align 4
105  store i32 1, ptr addrspacecast (ptr addrspace(3) @ReachableKernel to ptr), align 4
106  ret void
107}
108
109define internal void @level2Kernela() {
110; TUNIT: Function Attrs: norecurse nosync nounwind
111; TUNIT-LABEL: define {{[^@]+}}@level2Kernela
112; TUNIT-SAME: () #[[ATTR1]] {
113; TUNIT-NEXT:  entry:
114; TUNIT-NEXT:    [[TMP0:%.*]] = load i32, ptr addrspace(3) @ReachableKernel, align 4
115; TUNIT-NEXT:    [[TMP1:%.*]] = load i32, ptr @ReachableKernelAS0, align 4
116; TUNIT-NEXT:    [[TMP2:%.*]] = load i32, ptr addrspace(3) @UnreachableKernel, align 4
117; TUNIT-NEXT:    call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef [[TMP2]]) #[[ATTR7:[0-9]+]]
118; TUNIT-NEXT:    ret void
119;
120; CGSCC: Function Attrs: nosync nounwind
121; CGSCC-LABEL: define {{[^@]+}}@level2Kernela
122; CGSCC-SAME: () #[[ATTR3:[0-9]+]] {
123; CGSCC-NEXT:  entry:
124; CGSCC-NEXT:    [[TMP0:%.*]] = load i32, ptr addrspace(3) @ReachableKernel, align 4
125; CGSCC-NEXT:    [[TMP1:%.*]] = load i32, ptr @ReachableKernelAS0, align 4
126; CGSCC-NEXT:    [[TMP2:%.*]] = load i32, ptr addrspace(3) @UnreachableKernel, align 4
127; CGSCC-NEXT:    call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef [[TMP2]]) #[[ATTR4]]
128; CGSCC-NEXT:    ret void
129;
130entry:
131  %0 = load i32, ptr addrspacecast (ptr addrspace(3) @ReachableKernel to ptr), align 4
132  %1 = load i32, ptr @ReachableKernelAS0, align 4
133  %2 = load i32, ptr addrspacecast (ptr addrspace(3) @UnreachableKernel to ptr), align 4
134  call void @use(i32 %0, i32 %1, i32 %2)
135  ret void
136}
137
138define internal void @level2Kernelb() {
139; TUNIT: Function Attrs: norecurse nosync nounwind
140; TUNIT-LABEL: define {{[^@]+}}@level2Kernelb
141; TUNIT-SAME: () #[[ATTR1]] {
142; TUNIT-NEXT:  entry:
143; TUNIT-NEXT:    [[TMP0:%.*]] = load i32, ptr addrspace(3) @ReachableKernel, align 4
144; TUNIT-NEXT:    [[TMP1:%.*]] = load i32, ptr @ReachableKernelAS0, align 4
145; TUNIT-NEXT:    [[TMP2:%.*]] = load i32, ptr addrspace(3) @UnreachableKernel, align 4
146; TUNIT-NEXT:    call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef [[TMP2]]) #[[ATTR7]]
147; TUNIT-NEXT:    ret void
148;
149; CGSCC: Function Attrs: nosync nounwind
150; CGSCC-LABEL: define {{[^@]+}}@level2Kernelb
151; CGSCC-SAME: () #[[ATTR3]] {
152; CGSCC-NEXT:  entry:
153; CGSCC-NEXT:    [[TMP0:%.*]] = load i32, ptr addrspace(3) @ReachableKernel, align 4
154; CGSCC-NEXT:    [[TMP1:%.*]] = load i32, ptr @ReachableKernelAS0, align 4
155; CGSCC-NEXT:    [[TMP2:%.*]] = load i32, ptr addrspace(3) @UnreachableKernel, align 4
156; CGSCC-NEXT:    call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 noundef [[TMP2]]) #[[ATTR4]]
157; CGSCC-NEXT:    ret void
158;
159entry:
160  %0 = load i32, ptr addrspacecast (ptr addrspace(3) @ReachableKernel to ptr), align 4
161  %1 = load i32, ptr @ReachableKernelAS0, align 4
162  %2 = load i32, ptr addrspacecast (ptr addrspace(3) @UnreachableKernel to ptr), align 4
163  call void @use(i32 %0, i32 %1, i32 %2)
164  ret void
165}
166
167define internal void @level2Kernelall_late() {
168; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
169; CHECK-LABEL: define {{[^@]+}}@level2Kernelall_late
170; CHECK-SAME: () #[[ATTR2]] {
171; CHECK-NEXT:  entry:
172; CHECK-NEXT:    store i32 1, ptr addrspace(3) @UnreachableKernel, align 4
173; CHECK-NEXT:    ret void
174;
175entry:
176  store i32 1, ptr addrspacecast (ptr addrspace(3) @UnreachableKernel to ptr), align 4
177  ret void
178}
179
180@ReachableNonKernel = internal addrspace(3) global i32 0, align 4
181@UnreachableNonKernel = internal addrspace(3) global i32 0, align 4
182
183define dso_local void @non_kernel(i32 %C) norecurse {
184; TUNIT: Function Attrs: norecurse nosync nounwind
185; TUNIT-LABEL: define {{[^@]+}}@non_kernel
186; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
187; TUNIT-NEXT:  entry:
188; TUNIT-NEXT:    call void @level1(i32 [[C]]) #[[ATTR1]]
189; TUNIT-NEXT:    ret void
190;
191; CGSCC: Function Attrs: norecurse nosync nounwind
192; CGSCC-LABEL: define {{[^@]+}}@non_kernel
193; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
194; CGSCC-NEXT:  entry:
195; CGSCC-NEXT:    call void @level1(i32 [[C]]) #[[ATTR4]]
196; CGSCC-NEXT:    ret void
197;
198entry:
199  call void @level1(i32 %C)
200  ret void
201}
202
203define internal void @level1(i32 %C) {
204; TUNIT: Function Attrs: norecurse nosync nounwind
205; TUNIT-LABEL: define {{[^@]+}}@level1
206; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
207; TUNIT-NEXT:  entry:
208; TUNIT-NEXT:    [[LOCAL_ALLOCA:%.*]] = alloca i32, align 4, addrspace(5)
209; TUNIT-NEXT:    [[LOCAL:%.*]] = addrspacecast ptr addrspace(5) [[LOCAL_ALLOCA]] to ptr
210; TUNIT-NEXT:    call void @level2all_early(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[LOCAL]]) #[[ATTR4]]
211; TUNIT-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0
212; TUNIT-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
213; TUNIT:       if.then:
214; TUNIT-NEXT:    call void @level2a() #[[ATTR5]]
215; TUNIT-NEXT:    br label [[IF_END:%.*]]
216; TUNIT:       if.else:
217; TUNIT-NEXT:    call void @level2b() #[[ATTR5]]
218; TUNIT-NEXT:    br label [[IF_END]]
219; TUNIT:       if.end:
220; TUNIT-NEXT:    call void @level2all_late(ptr nofree noundef writeonly align 4 captures(none) dereferenceable_or_null(4) [[LOCAL]]) #[[ATTR6]]
221; TUNIT-NEXT:    ret void
222;
223; CGSCC: Function Attrs: norecurse nosync nounwind
224; CGSCC-LABEL: define {{[^@]+}}@level1
225; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
226; CGSCC-NEXT:  entry:
227; CGSCC-NEXT:    [[LOCAL_ALLOCA:%.*]] = alloca i32, align 4, addrspace(5)
228; CGSCC-NEXT:    [[LOCAL:%.*]] = addrspacecast ptr addrspace(5) [[LOCAL_ALLOCA]] to ptr
229; CGSCC-NEXT:    call void @level2all_early(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[LOCAL]]) #[[ATTR5]]
230; CGSCC-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[C]], 0
231; CGSCC-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
232; CGSCC:       if.then:
233; CGSCC-NEXT:    call void @level2a(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOCAL]]) #[[ATTR4]]
234; CGSCC-NEXT:    br label [[IF_END:%.*]]
235; CGSCC:       if.else:
236; CGSCC-NEXT:    call void @level2b(ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[LOCAL]]) #[[ATTR4]]
237; CGSCC-NEXT:    br label [[IF_END]]
238; CGSCC:       if.end:
239; CGSCC-NEXT:    call void @level2all_late(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[LOCAL]]) #[[ATTR6]]
240; CGSCC-NEXT:    ret void
241;
242entry:
243  %local.alloca = alloca i32, addrspace(5)
244  %local = addrspacecast ptr addrspace(5) %local.alloca to ptr
245  call void @level2all_early(ptr %local)
246  %tobool = icmp ne i32 %C, 0
247  br i1 %tobool, label %if.then, label %if.else
248
249if.then:                                          ; preds = %entry
250  call void @level2a(ptr %local)
251  br label %if.end
252
253if.else:                                          ; preds = %entry
254  call void @level2b(ptr %local)
255  br label %if.end
256
257if.end:                                           ; preds = %if.else, %if.then
258  call void @level2all_late(ptr %local)
259  ret void
260}
261
262define internal void @level2all_early(ptr %addr) {
263; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
264; TUNIT-LABEL: define {{[^@]+}}@level2all_early
265; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
266; TUNIT-NEXT:  entry:
267; TUNIT-NEXT:    store i32 1, ptr addrspace(3) @ReachableNonKernel, align 4
268; TUNIT-NEXT:    [[TMP0:%.*]] = addrspacecast ptr [[ADDR]] to ptr addrspace(5)
269; TUNIT-NEXT:    ret void
270;
271; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
272; CGSCC-LABEL: define {{[^@]+}}@level2all_early
273; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
274; CGSCC-NEXT:  entry:
275; CGSCC-NEXT:    store i32 1, ptr addrspace(3) @ReachableNonKernel, align 4
276; CGSCC-NEXT:    store i32 17, ptr [[ADDR]], align 4
277; CGSCC-NEXT:    ret void
278;
279entry:
280  store i32 1, ptr addrspacecast (ptr addrspace(3) @ReachableNonKernel to ptr), align 4
281  store i32 17, ptr %addr, align 4
282  ret void
283}
284
285define internal void @level2a(ptr %addr) {
286; TUNIT: Function Attrs: norecurse nosync nounwind memory(readwrite, argmem: none)
287; TUNIT-LABEL: define {{[^@]+}}@level2a
288; TUNIT-SAME: () #[[ATTR3:[0-9]+]] {
289; TUNIT-NEXT:  entry:
290; TUNIT-NEXT:    [[TMP0:%.*]] = load i32, ptr addrspace(3) @ReachableNonKernel, align 4
291; TUNIT-NEXT:    [[TMP1:%.*]] = load i32, ptr addrspace(3) @UnreachableNonKernel, align 4
292; TUNIT-NEXT:    call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR7]]
293; TUNIT-NEXT:    ret void
294;
295; CGSCC: Function Attrs: nosync nounwind
296; CGSCC-LABEL: define {{[^@]+}}@level2a
297; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[ADDR:%.*]]) #[[ATTR3]] {
298; CGSCC-NEXT:  entry:
299; CGSCC-NEXT:    [[TMP0:%.*]] = load i32, ptr addrspace(3) @ReachableNonKernel, align 4
300; CGSCC-NEXT:    [[TMP1:%.*]] = load i32, ptr addrspace(3) @UnreachableNonKernel, align 4
301; CGSCC-NEXT:    [[QQQQ2:%.*]] = load i32, ptr [[ADDR]], align 4
302; CGSCC-NEXT:    call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 [[QQQQ2]]) #[[ATTR4]]
303; CGSCC-NEXT:    ret void
304;
305entry:
306  %0 = load i32, ptr addrspacecast (ptr addrspace(3) @ReachableNonKernel to ptr), align 4
307  %1 = load i32, ptr addrspacecast (ptr addrspace(3) @UnreachableNonKernel to ptr), align 4
308  %qqqq2 = load i32, ptr %addr
309  call void @use(i32 %0, i32 %1, i32 %qqqq2)
310  ret void
311}
312
313define internal void @level2b(ptr %addr) {
314; TUNIT: Function Attrs: norecurse nosync nounwind memory(readwrite, argmem: none)
315; TUNIT-LABEL: define {{[^@]+}}@level2b
316; TUNIT-SAME: () #[[ATTR3]] {
317; TUNIT-NEXT:  entry:
318; TUNIT-NEXT:    [[TMP0:%.*]] = load i32, ptr addrspace(3) @ReachableNonKernel, align 4
319; TUNIT-NEXT:    [[TMP1:%.*]] = load i32, ptr addrspace(3) @UnreachableNonKernel, align 4
320; TUNIT-NEXT:    call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR7]]
321; TUNIT-NEXT:    ret void
322;
323; CGSCC: Function Attrs: nosync nounwind
324; CGSCC-LABEL: define {{[^@]+}}@level2b
325; CGSCC-SAME: (ptr nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[ADDR:%.*]]) #[[ATTR3]] {
326; CGSCC-NEXT:  entry:
327; CGSCC-NEXT:    [[TMP0:%.*]] = load i32, ptr addrspace(3) @ReachableNonKernel, align 4
328; CGSCC-NEXT:    [[TMP1:%.*]] = load i32, ptr addrspace(3) @UnreachableNonKernel, align 4
329; CGSCC-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ADDR]], align 4
330; CGSCC-NEXT:    call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 [[TMP2]]) #[[ATTR4]]
331; CGSCC-NEXT:    ret void
332;
333entry:
334  %0 = load i32, ptr addrspacecast (ptr addrspace(3) @ReachableNonKernel to ptr), align 4
335  %1 = load i32, ptr addrspacecast (ptr addrspace(3) @UnreachableNonKernel to ptr), align 4
336  %2 = load i32, ptr %addr
337  call void @use(i32 %0, i32 %1, i32 %2)
338  ret void
339}
340
341define internal void @level2all_late(ptr %addr) {
342; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
343; TUNIT-LABEL: define {{[^@]+}}@level2all_late
344; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
345; TUNIT-NEXT:  entry:
346; TUNIT-NEXT:    store i32 1, ptr addrspace(3) @UnreachableNonKernel, align 4
347; TUNIT-NEXT:    [[TMP0:%.*]] = addrspacecast ptr [[ADDR]] to ptr addrspace(5)
348; TUNIT-NEXT:    ret void
349;
350; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
351; CGSCC-LABEL: define {{[^@]+}}@level2all_late
352; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[ADDR:%.*]]) #[[ATTR2]] {
353; CGSCC-NEXT:  entry:
354; CGSCC-NEXT:    store i32 1, ptr addrspace(3) @UnreachableNonKernel, align 4
355; CGSCC-NEXT:    store i32 5, ptr [[ADDR]], align 4
356; CGSCC-NEXT:    ret void
357;
358entry:
359  store i32 1, ptr addrspacecast (ptr addrspace(3) @UnreachableNonKernel to ptr), align 4
360  store i32 5, ptr %addr, align 4
361  ret void
362}
363
364define dso_local void @kernel2(i32 %C) norecurse "kernel" {
365; TUNIT: Function Attrs: norecurse nosync nounwind
366; TUNIT-LABEL: define {{[^@]+}}@kernel2
367; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
368; TUNIT-NEXT:    [[I:%.*]] = icmp eq i32 [[C]], 42
369; TUNIT-NEXT:    br i1 [[I]], label [[T:%.*]], label [[F:%.*]]
370; TUNIT:       t:
371; TUNIT-NEXT:    store i32 333, ptr addrspace(3) @AS3OneKernelAtATime, align 4
372; TUNIT-NEXT:    br label [[F]]
373; TUNIT:       f:
374; TUNIT-NEXT:    [[L:%.*]] = load i32, ptr addrspace(3) @AS3OneKernelAtATime, align 4
375; TUNIT-NEXT:    call void @use(i32 noundef [[L]], i32 noundef [[L]], i32 noundef [[L]]) #[[ATTR7]]
376; TUNIT-NEXT:    ret void
377;
378; CGSCC: Function Attrs: norecurse nosync nounwind
379; CGSCC-LABEL: define {{[^@]+}}@kernel2
380; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
381; CGSCC-NEXT:    [[I:%.*]] = icmp eq i32 [[C]], 42
382; CGSCC-NEXT:    br i1 [[I]], label [[T:%.*]], label [[F:%.*]]
383; CGSCC:       t:
384; CGSCC-NEXT:    store i32 333, ptr addrspace(3) @AS3OneKernelAtATime, align 4
385; CGSCC-NEXT:    br label [[F]]
386; CGSCC:       f:
387; CGSCC-NEXT:    [[L:%.*]] = load i32, ptr addrspace(3) @AS3OneKernelAtATime, align 4
388; CGSCC-NEXT:    call void @use(i32 noundef [[L]], i32 noundef [[L]], i32 noundef [[L]]) #[[ATTR4]]
389; CGSCC-NEXT:    ret void
390;
391  %i = icmp eq i32 %C, 42
392  br i1 %i, label %t, label %f
393t:
394  store i32 333, ptr addrspace(3) @AS3OneKernelAtATime
395  br label %f
396f:
397  %l = load i32, ptr addrspace(3) @AS3OneKernelAtATime
398  call void @use(i32 %l,i32 %l, i32 %l)
399  ret void
400}
401
402define dso_local void @kernel3(i32 %C) norecurse "kernel" {
403; TUNIT: Function Attrs: norecurse nosync nounwind
404; TUNIT-LABEL: define {{[^@]+}}@kernel3
405; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
406; TUNIT-NEXT:    [[I:%.*]] = icmp eq i32 [[C]], 42
407; TUNIT-NEXT:    br i1 [[I]], label [[T:%.*]], label [[F:%.*]]
408; TUNIT:       t:
409; TUNIT-NEXT:    call void @use(i32 noundef 42, i32 noundef 42, i32 noundef 42) #[[ATTR7]]
410; TUNIT-NEXT:    ret void
411; TUNIT:       f:
412; TUNIT-NEXT:    ret void
413;
414; CGSCC: Function Attrs: norecurse nosync nounwind
415; CGSCC-LABEL: define {{[^@]+}}@kernel3
416; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
417; CGSCC-NEXT:    [[I:%.*]] = icmp eq i32 [[C]], 42
418; CGSCC-NEXT:    br i1 [[I]], label [[T:%.*]], label [[F:%.*]]
419; CGSCC:       t:
420; CGSCC-NEXT:    call void @use(i32 noundef 42, i32 noundef 42, i32 noundef 42) #[[ATTR4]]
421; CGSCC-NEXT:    ret void
422; CGSCC:       f:
423; CGSCC-NEXT:    ret void
424;
425  %i = icmp eq i32 %C, 42
426  br i1 %i, label %t, label %f
427t:
428  %l = load i32, ptr addrspace(3) @AS3OneKernelAtATime
429  call void @use(i32 %l,i32 %l, i32 %l)
430  ret void
431f:
432  ret void
433}
434
435declare dso_local void @use(i32, i32, i32) nosync norecurse nounwind
436
437;.
438; TUNIT: attributes #[[ATTR0]] = { norecurse nosync nounwind "kernel" }
439; TUNIT: attributes #[[ATTR1]] = { norecurse nosync nounwind }
440; TUNIT: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
441; TUNIT: attributes #[[ATTR3]] = { norecurse nosync nounwind memory(readwrite, argmem: none) }
442; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn memory(write) }
443; TUNIT: attributes #[[ATTR5]] = { nosync nounwind }
444; TUNIT: attributes #[[ATTR6]] = { nosync nounwind memory(write) }
445; TUNIT: attributes #[[ATTR7]] = { nounwind }
446;.
447; CGSCC: attributes #[[ATTR0]] = { norecurse nosync nounwind "kernel" }
448; CGSCC: attributes #[[ATTR1]] = { norecurse nosync nounwind }
449; CGSCC: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
450; CGSCC: attributes #[[ATTR3]] = { nosync nounwind }
451; CGSCC: attributes #[[ATTR4]] = { nounwind }
452; CGSCC: attributes #[[ATTR5]] = { nofree nounwind willreturn memory(write) }
453; CGSCC: attributes #[[ATTR6]] = { nounwind memory(write) }
454;.
455