1; RUN: llc -mtriple=amdgcn--amdpal -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,SDAG,GFX8 -enable-var-scope %s
2; RUN: llc -mtriple=amdgcn--amdpal -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,SDAG,GFX9 -enable-var-scope %s
3; RUN: llc -global-isel -mtriple=amdgcn--amdpal -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,GISEL,GFX9 -enable-var-scope %s
4
5; Make sure this interacts well with -amdgpu-fixed-function-abi
6; RUN: llc -mtriple=amdgcn--amdpal -mcpu=gfx900 -amdgpu-fixed-function-abi -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,SDAG,GFX9 -enable-var-scope %s
7
8declare float @extern_func(float) #0
9declare float @extern_func_many_args(<64 x float>) #0
10
11@funcptr = external hidden unnamed_addr addrspace(4) constant void()*, align 4
12
13define amdgpu_gfx float @no_stack(float %arg0) #0 {
14  %add = fadd float %arg0, 1.0
15  ret float %add
16}
17
18define amdgpu_gfx float @simple_stack(float %arg0) #0 {
19  %stack = alloca float, i32 4, align 4, addrspace(5)
20  store volatile float 2.0, float addrspace(5)* %stack
21  %val = load volatile float, float addrspace(5)* %stack
22  %add = fadd float %arg0, %val
23  ret float %add
24}
25
26define amdgpu_gfx float @multiple_stack(float %arg0) #0 {
27  %stack = alloca float, i32 4, align 4, addrspace(5)
28  store volatile float 2.0, float addrspace(5)* %stack
29  %val = load volatile float, float addrspace(5)* %stack
30  %add = fadd float %arg0, %val
31  %stack2 = alloca float, i32 4, align 4, addrspace(5)
32  store volatile float 2.0, float addrspace(5)* %stack2
33  %val2 = load volatile float, float addrspace(5)* %stack2
34  %add2 = fadd float %add, %val2
35  ret float %add2
36}
37
38define amdgpu_gfx float @dynamic_stack(float %arg0) #0 {
39bb0:
40  %cmp = fcmp ogt float %arg0, 0.0
41  br i1 %cmp, label %bb1, label %bb2
42
43bb1:
44  %stack = alloca float, i32 4, align 4, addrspace(5)
45  store volatile float 2.0, float addrspace(5)* %stack
46  %val = load volatile float, float addrspace(5)* %stack
47  %add = fadd float %arg0, %val
48  br label %bb2
49
50bb2:
51  %res = phi float [ 0.0, %bb0 ], [ %add, %bb1 ]
52  ret float %res
53}
54
55define amdgpu_gfx float @dynamic_stack_loop(float %arg0) #0 {
56bb0:
57  br label %bb1
58
59bb1:
60  %ctr = phi i32 [ 0, %bb0 ], [ %newctr, %bb1 ]
61  %stack = alloca float, i32 4, align 4, addrspace(5)
62  store volatile float 2.0, float addrspace(5)* %stack
63  %val = load volatile float, float addrspace(5)* %stack
64  %add = fadd float %arg0, %val
65  %cmp = icmp sgt i32 %ctr, 0
66  %newctr = sub i32 %ctr, 1
67  br i1 %cmp, label %bb1, label %bb2
68
69bb2:
70  ret float %add
71}
72
73define amdgpu_gfx float @no_stack_call(float %arg0) #0 {
74  %res = call amdgpu_gfx float @simple_stack(float %arg0)
75  ret float %res
76}
77
78define amdgpu_gfx float @simple_stack_call(float %arg0) #0 {
79  %stack = alloca float, i32 4, align 4, addrspace(5)
80  store volatile float 2.0, float addrspace(5)* %stack
81  %val = load volatile float, float addrspace(5)* %stack
82  %res = call amdgpu_gfx float @simple_stack(float %arg0)
83  %add = fadd float %res, %val
84  ret float %add
85}
86
87define amdgpu_gfx float @no_stack_extern_call(float %arg0) #0 {
88  %res = call amdgpu_gfx float @extern_func(float %arg0)
89  ret float %res
90}
91
92define amdgpu_gfx float @simple_stack_extern_call(float %arg0) #0 {
93  %stack = alloca float, i32 4, align 4, addrspace(5)
94  store volatile float 2.0, float addrspace(5)* %stack
95  %val = load volatile float, float addrspace(5)* %stack
96  %res = call amdgpu_gfx float @extern_func(float %arg0)
97  %add = fadd float %res, %val
98  ret float %add
99}
100
101define amdgpu_gfx float @no_stack_extern_call_many_args(<64 x float> %arg0) #0 {
102  %res = call amdgpu_gfx float @extern_func_many_args(<64 x float> %arg0)
103  ret float %res
104}
105
106define amdgpu_gfx float @no_stack_indirect_call(float %arg0) #0 {
107  %fptr = load void()*, void()* addrspace(4)* @funcptr
108  call amdgpu_gfx void %fptr()
109  ret float %arg0
110}
111
112define amdgpu_gfx float @simple_stack_indirect_call(float %arg0) #0 {
113  %stack = alloca float, i32 4, align 4, addrspace(5)
114  store volatile float 2.0, float addrspace(5)* %stack
115  %val = load volatile float, float addrspace(5)* %stack
116  %fptr = load void()*, void()* addrspace(4)* @funcptr
117  call amdgpu_gfx void %fptr()
118  %add = fadd float %arg0, %val
119  ret float %add
120}
121
122define amdgpu_gfx float @simple_stack_recurse(float %arg0) #0 {
123  %stack = alloca float, i32 4, align 4, addrspace(5)
124  store volatile float 2.0, float addrspace(5)* %stack
125  %val = load volatile float, float addrspace(5)* %stack
126  %res = call amdgpu_gfx float @simple_stack_recurse(float %arg0)
127  %add = fadd float %res, %val
128  ret float %add
129}
130
131@lds = internal addrspace(3) global [64 x float] undef
132
133define amdgpu_gfx float @simple_lds(float %arg0) #0 {
134  %lds_ptr = getelementptr [64 x float], [64 x float] addrspace(3)* @lds, i32 0, i32 0
135  %val = load float, float addrspace(3)* %lds_ptr
136  ret float %val
137}
138
139define amdgpu_gfx float @simple_lds_recurse(float %arg0) #0 {
140  %lds_ptr = getelementptr [64 x float], [64 x float] addrspace(3)* @lds, i32 0, i32 0
141  %val = load float, float addrspace(3)* %lds_ptr
142  %res = call amdgpu_gfx float @simple_lds_recurse(float %val)
143  ret float %res
144}
145
146attributes #0 = { nounwind }
147
148; GCN: amdpal.pipelines:
149; GCN-NEXT:  - .registers:
150; SDAG-NEXT:      0x2e12 (COMPUTE_PGM_RSRC1): 0xaf01ca{{$}}
151; GISEL-NEXT:      0x2e12 (COMPUTE_PGM_RSRC1): 0xaf01ce{{$}}
152; GCN-NEXT:      0x2e13 (COMPUTE_PGM_RSRC2): 0x8001{{$}}
153; GCN-NEXT:    .shader_functions:
154; GCN-NEXT:      dynamic_stack:
155; GCN-NEXT:        .lds_size:       0{{$}}
156; GCN-NEXT:        .sgpr_count:     0x24{{$}}
157; GCN-NEXT:        .stack_frame_size_in_bytes: 0x10{{$}}
158; SDAG-NEXT:        .vgpr_count:     0x2{{$}}
159; GISEL-NEXT:        .vgpr_count:     0x3{{$}}
160; GCN-NEXT:      dynamic_stack_loop:
161; GCN-NEXT:        .lds_size:       0{{$}}
162; SDAG-NEXT:        .sgpr_count:     0x22{{$}}
163; GISEL-NEXT:        .sgpr_count:     0x24{{$}}
164; GCN-NEXT:        .stack_frame_size_in_bytes: 0x10{{$}}
165; SDAG-NEXT:        .vgpr_count:     0x3{{$}}
166; GISEL-NEXT:        .vgpr_count:     0x4{{$}}
167; GCN-NEXT:      multiple_stack:
168; GCN-NEXT:        .lds_size:       0{{$}}
169; GCN-NEXT:        .sgpr_count:     0x21{{$}}
170; GCN-NEXT:        .stack_frame_size_in_bytes: 0x24{{$}}
171; GCN-NEXT:        .vgpr_count:     0x3{{$}}
172; GCN-NEXT:      no_stack:
173; GCN-NEXT:        .lds_size:       0{{$}}
174; GCN-NEXT:        .sgpr_count:     0x20{{$}}
175; GCN-NEXT:        .stack_frame_size_in_bytes: 0{{$}}
176; GCN-NEXT:        .vgpr_count:     0x1{{$}}
177; GCN-NEXT:      no_stack_call:
178; GCN-NEXT:        .lds_size:       0{{$}}
179; GCN-NEXT:        .sgpr_count:     0x21{{$}}
180; GCN-NEXT:        .stack_frame_size_in_bytes: 0{{$}}
181; GCN-NEXT:        .vgpr_count:     0x2{{$}}
182; GCN-NEXT:      no_stack_extern_call:
183; GCN-NEXT:        .lds_size:       0{{$}}
184; GFX8-NEXT:        .sgpr_count:     0x24{{$}}
185; GFX9-NEXT:        .sgpr_count:     0x28{{$}}
186; GCN-NEXT:        .stack_frame_size_in_bytes: 0x10{{$}}
187; GCN-NEXT:        .vgpr_count:     0x29{{$}}
188; GCN-NEXT:      no_stack_extern_call_many_args:
189; GCN-NEXT:        .lds_size:       0{{$}}
190; GFX8-NEXT:        .sgpr_count:     0x24{{$}}
191; GFX9-NEXT:        .sgpr_count:     0x28{{$}}
192; GCN-NEXT:        .stack_frame_size_in_bytes: 0x90{{$}}
193; SDAG-NEXT:        .vgpr_count:     0x2a{{$}}
194; GISEL-NEXT:        .vgpr_count:     0x34{{$}}
195; GCN-NEXT:      no_stack_indirect_call:
196; GCN-NEXT:        .lds_size:       0{{$}}
197; GFX8-NEXT:        .sgpr_count:     0x24{{$}}
198; GFX9-NEXT:        .sgpr_count:     0x28{{$}}
199; GCN-NEXT:        .stack_frame_size_in_bytes: 0x10{{$}}
200; SDAG-NEXT:        .vgpr_count:     0x2a{{$}}
201; GISEL-NEXT:        .vgpr_count:     0x34{{$}}
202; GCN-NEXT:      simple_lds:
203; GCN-NEXT:        .lds_size:       0x100{{$}}
204; GCN-NEXT:        .sgpr_count:     0x20{{$}}
205; GCN-NEXT:        .stack_frame_size_in_bytes: 0{{$}}
206; GCN-NEXT:        .vgpr_count:     0x1{{$}}
207; GCN-NEXT:      simple_lds_recurse:
208; GCN-NEXT:        .lds_size:       0x100{{$}}
209; GCN-NEXT:        .sgpr_count:     0x24{{$}}
210; GCN-NEXT:        .stack_frame_size_in_bytes: 0x10{{$}}
211; GCN-NEXT:        .vgpr_count:     0x29{{$}}
212; GCN-NEXT:      simple_stack:
213; GCN-NEXT:        .lds_size:       0{{$}}
214; GCN-NEXT:        .sgpr_count:     0x21{{$}}
215; GCN-NEXT:        .stack_frame_size_in_bytes: 0x14{{$}}
216; GCN-NEXT:        .vgpr_count:     0x2{{$}}
217; GCN-NEXT:      simple_stack_call:
218; GCN-NEXT:        .lds_size:       0{{$}}
219; GCN-NEXT:        .sgpr_count:     0x22{{$}}
220; GCN-NEXT:        .stack_frame_size_in_bytes: 0x20{{$}}
221; GCN-NEXT:        .vgpr_count:     0x3{{$}}
222; GCN-NEXT:      simple_stack_extern_call:
223; GCN-NEXT:        .lds_size:       0{{$}}
224; GFX8-NEXT:        .sgpr_count:     0x24{{$}}
225; GFX9-NEXT:        .sgpr_count:     0x28{{$}}
226; GCN-NEXT:        .stack_frame_size_in_bytes: 0x20{{$}}
227; GCN-NEXT:        .vgpr_count:     0x2a{{$}}
228; GCN-NEXT:      simple_stack_indirect_call:
229; GCN-NEXT:        .lds_size:       0{{$}}
230; GFX8-NEXT:        .sgpr_count:     0x24{{$}}
231; GFX9-NEXT:        .sgpr_count:     0x28{{$}}
232; GCN-NEXT:        .stack_frame_size_in_bytes: 0x20{{$}}
233; SDAG-NEXT:        .vgpr_count:     0x2b{{$}}
234; GISEL-NEXT:        .vgpr_count:     0x34{{$}}
235; GCN-NEXT:      simple_stack_recurse:
236; GCN-NEXT:        .lds_size:       0{{$}}
237; GCN-NEXT:        .sgpr_count:     0x24{{$}}
238; GCN-NEXT:        .stack_frame_size_in_bytes: 0x20{{$}}
239; GCN-NEXT:        .vgpr_count:     0x2a{{$}}
240; GCN-NEXT: ...
241