[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / AMDGPU / uniform-work-group-recursion-test.ll
blob2397c2b0e3f81bed9bec3d6b3d6b2caebd138c2b
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-globals
2 ; RUN: opt -S -mtriple=amdgcn-amd- -amdgpu-annotate-kernel-features %s | FileCheck --allow-unused-prefixes -check-prefixes=CHECK,AKF_CHECK %s
3 ; RUN: opt -S -mtriple=amdgcn-amd- -amdgpu-attributor %s | FileCheck --allow-unused-prefixes -check-prefixes=CHECK,ATTRIBUTOR_CHECK %s
5 ; Test to ensure recursive functions exhibit proper behaviour
6 ; Test to generate fibonacci numbers
8 define i32 @fib(i32 %n) #0 {
9 ; AKF_CHECK-LABEL: define {{[^@]+}}@fib
10 ; AKF_CHECK-SAME: (i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] {
11 ; AKF_CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[N]], 0
12 ; AKF_CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[CONT1:%.*]]
13 ; AKF_CHECK:       cont1:
14 ; AKF_CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[N]], 1
15 ; AKF_CHECK-NEXT:    br i1 [[CMP2]], label [[EXIT]], label [[CONT2:%.*]]
16 ; AKF_CHECK:       cont2:
17 ; AKF_CHECK-NEXT:    [[NM1:%.*]] = sub i32 [[N]], 1
18 ; AKF_CHECK-NEXT:    [[FIBM1:%.*]] = call i32 @fib(i32 [[NM1]])
19 ; AKF_CHECK-NEXT:    [[NM2:%.*]] = sub i32 [[N]], 2
20 ; AKF_CHECK-NEXT:    [[FIBM2:%.*]] = call i32 @fib(i32 [[NM2]])
21 ; AKF_CHECK-NEXT:    [[RETVAL:%.*]] = add i32 [[FIBM1]], [[FIBM2]]
22 ; AKF_CHECK-NEXT:    ret i32 [[RETVAL]]
23 ; AKF_CHECK:       exit:
24 ; AKF_CHECK-NEXT:    ret i32 1
26 ; ATTRIBUTOR_CHECK-LABEL: define {{[^@]+}}@fib
27 ; ATTRIBUTOR_CHECK-SAME: (i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] {
28 ; ATTRIBUTOR_CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[N]], 0
29 ; ATTRIBUTOR_CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[CONT1:%.*]]
30 ; ATTRIBUTOR_CHECK:       cont1:
31 ; ATTRIBUTOR_CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[N]], 1
32 ; ATTRIBUTOR_CHECK-NEXT:    br i1 [[CMP2]], label [[EXIT]], label [[CONT2:%.*]]
33 ; ATTRIBUTOR_CHECK:       cont2:
34 ; ATTRIBUTOR_CHECK-NEXT:    [[NM1:%.*]] = sub i32 [[N]], 1
35 ; ATTRIBUTOR_CHECK-NEXT:    [[FIBM1:%.*]] = call i32 @fib(i32 [[NM1]]) #[[ATTR3:[0-9]+]]
36 ; ATTRIBUTOR_CHECK-NEXT:    [[NM2:%.*]] = sub i32 [[N]], 2
37 ; ATTRIBUTOR_CHECK-NEXT:    [[FIBM2:%.*]] = call i32 @fib(i32 [[NM2]]) #[[ATTR3]]
38 ; ATTRIBUTOR_CHECK-NEXT:    [[RETVAL:%.*]] = add i32 [[FIBM1]], [[FIBM2]]
39 ; ATTRIBUTOR_CHECK-NEXT:    ret i32 [[RETVAL]]
40 ; ATTRIBUTOR_CHECK:       exit:
41 ; ATTRIBUTOR_CHECK-NEXT:    ret i32 1
43   %cmp1 = icmp eq i32 %n, 0
44   br i1 %cmp1, label %exit, label %cont1
46 cont1:
47   %cmp2 = icmp eq i32 %n, 1
48   br i1 %cmp2, label %exit, label %cont2
50 cont2:
51   %nm1 = sub i32 %n, 1
52   %fibm1 = call i32 @fib(i32 %nm1)
53   %nm2 = sub i32 %n, 2
54   %fibm2 = call i32 @fib(i32 %nm2)
55   %retval = add i32 %fibm1, %fibm2
57   ret i32 %retval
59 exit:
60   ret i32 1
63 define internal i32 @fib_internal(i32 %n) #0 {
64 ; AKF_CHECK-LABEL: define {{[^@]+}}@fib_internal
65 ; AKF_CHECK-SAME: (i32 [[N:%.*]]) #[[ATTR0]] {
66 ; AKF_CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[N]], 0
67 ; AKF_CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[CONT1:%.*]]
68 ; AKF_CHECK:       cont1:
69 ; AKF_CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[N]], 1
70 ; AKF_CHECK-NEXT:    br i1 [[CMP2]], label [[EXIT]], label [[CONT2:%.*]]
71 ; AKF_CHECK:       cont2:
72 ; AKF_CHECK-NEXT:    [[NM1:%.*]] = sub i32 [[N]], 1
73 ; AKF_CHECK-NEXT:    [[FIBM1:%.*]] = call i32 @fib_internal(i32 [[NM1]])
74 ; AKF_CHECK-NEXT:    [[NM2:%.*]] = sub i32 [[N]], 2
75 ; AKF_CHECK-NEXT:    [[FIBM2:%.*]] = call i32 @fib_internal(i32 [[NM2]])
76 ; AKF_CHECK-NEXT:    [[RETVAL:%.*]] = add i32 [[FIBM1]], [[FIBM2]]
77 ; AKF_CHECK-NEXT:    ret i32 [[RETVAL]]
78 ; AKF_CHECK:       exit:
79 ; AKF_CHECK-NEXT:    ret i32 1
81 ; ATTRIBUTOR_CHECK-LABEL: define {{[^@]+}}@fib_internal
82 ; ATTRIBUTOR_CHECK-SAME: (i32 [[N:%.*]]) #[[ATTR1:[0-9]+]] {
83 ; ATTRIBUTOR_CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[N]], 0
84 ; ATTRIBUTOR_CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[CONT1:%.*]]
85 ; ATTRIBUTOR_CHECK:       cont1:
86 ; ATTRIBUTOR_CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[N]], 1
87 ; ATTRIBUTOR_CHECK-NEXT:    br i1 [[CMP2]], label [[EXIT]], label [[CONT2:%.*]]
88 ; ATTRIBUTOR_CHECK:       cont2:
89 ; ATTRIBUTOR_CHECK-NEXT:    [[NM1:%.*]] = sub i32 [[N]], 1
90 ; ATTRIBUTOR_CHECK-NEXT:    [[FIBM1:%.*]] = call i32 @fib_internal(i32 [[NM1]]) #[[ATTR4:[0-9]+]]
91 ; ATTRIBUTOR_CHECK-NEXT:    [[NM2:%.*]] = sub i32 [[N]], 2
92 ; ATTRIBUTOR_CHECK-NEXT:    [[FIBM2:%.*]] = call i32 @fib_internal(i32 [[NM2]]) #[[ATTR4]]
93 ; ATTRIBUTOR_CHECK-NEXT:    [[RETVAL:%.*]] = add i32 [[FIBM1]], [[FIBM2]]
94 ; ATTRIBUTOR_CHECK-NEXT:    ret i32 [[RETVAL]]
95 ; ATTRIBUTOR_CHECK:       exit:
96 ; ATTRIBUTOR_CHECK-NEXT:    ret i32 1
98   %cmp1 = icmp eq i32 %n, 0
99   br i1 %cmp1, label %exit, label %cont1
101 cont1:
102   %cmp2 = icmp eq i32 %n, 1
103   br i1 %cmp2, label %exit, label %cont2
105 cont2:
106   %nm1 = sub i32 %n, 1
107   %fibm1 = call i32 @fib_internal(i32 %nm1)
108   %nm2 = sub i32 %n, 2
109   %fibm2 = call i32 @fib_internal(i32 %nm2)
110   %retval = add i32 %fibm1, %fibm2
112   ret i32 %retval
114 exit:
115   ret i32 1
118 define amdgpu_kernel void @kernel(i32 addrspace(1)* %m) #1 {
119 ; AKF_CHECK-LABEL: define {{[^@]+}}@kernel
120 ; AKF_CHECK-SAME: (i32 addrspace(1)* [[M:%.*]]) #[[ATTR1:[0-9]+]] {
121 ; AKF_CHECK-NEXT:    [[R:%.*]] = call i32 @fib(i32 5)
122 ; AKF_CHECK-NEXT:    [[R2:%.*]] = call i32 @fib_internal(i32 5)
123 ; AKF_CHECK-NEXT:    store i32 [[R]], i32 addrspace(1)* [[M]], align 4
124 ; AKF_CHECK-NEXT:    store i32 [[R2]], i32 addrspace(1)* [[M]], align 4
125 ; AKF_CHECK-NEXT:    ret void
127 ; ATTRIBUTOR_CHECK-LABEL: define {{[^@]+}}@kernel
128 ; ATTRIBUTOR_CHECK-SAME: (i32 addrspace(1)* [[M:%.*]]) #[[ATTR2:[0-9]+]] {
129 ; ATTRIBUTOR_CHECK-NEXT:    [[R:%.*]] = call i32 @fib(i32 5) #[[ATTR3]]
130 ; ATTRIBUTOR_CHECK-NEXT:    [[R2:%.*]] = call i32 @fib_internal(i32 noundef 5) #[[ATTR3]]
131 ; ATTRIBUTOR_CHECK-NEXT:    store i32 [[R]], i32 addrspace(1)* [[M]], align 4
132 ; ATTRIBUTOR_CHECK-NEXT:    store i32 [[R2]], i32 addrspace(1)* [[M]], align 4
133 ; ATTRIBUTOR_CHECK-NEXT:    ret void
135   %r = call i32 @fib(i32 5)
136   %r2 = call i32 @fib_internal(i32 5)
138   store i32 %r, i32 addrspace(1)* %m
139   store i32 %r2, i32 addrspace(1)* %m
140   ret void
143 ; nounwind and readnone are added to match attributor results.
144 attributes #0 = { nounwind readnone }
145 attributes #1 = { "uniform-work-group-size"="true" }
148 ; AKF_CHECK: attributes #[[ATTR0]] = { nounwind readnone "uniform-work-group-size"="true" }
149 ; AKF_CHECK: attributes #[[ATTR1]] = { "amdgpu-calls" "uniform-work-group-size"="true" }
151 ; ATTRIBUTOR_CHECK: attributes #[[ATTR0]] = { nounwind readnone "uniform-work-group-size"="false" }
152 ; ATTRIBUTOR_CHECK: attributes #[[ATTR1]] = { nofree nosync nounwind readnone "uniform-work-group-size"="true" }
153 ; ATTRIBUTOR_CHECK: attributes #[[ATTR2]] = { "amdgpu-calls" "uniform-work-group-size"="true" }
154 ; ATTRIBUTOR_CHECK: attributes #[[ATTR3]] = { nounwind readnone }
155 ; ATTRIBUTOR_CHECK: attributes #[[ATTR4]] = { nofree nounwind readnone }