Recommit r310809 with a fix for the spill problem
[llvm-core.git] / test / CodeGen / AMDGPU / madmk.ll
blobb78d65ae1e1a1627ce47376a04567f69a6379a07
1 ; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=SI %s
2 ; XUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=VI %s
4  ; FIXME: None of these trigger madmk emission anymore. It is still
5  ; possible, but requires the correct registers to be used which is
6  ; hard to trigger.
8 declare i32 @llvm.amdgcn.workitem.id.x() nounwind readnone
9 declare float @llvm.fabs.f32(float) nounwind readnone
11 ; GCN-LABEL: {{^}}madmk_f32:
12 ; GCN-DAG: buffer_load_dword [[VA:v[0-9]+]], {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64{{$}}
13 ; GCN-DAG: buffer_load_dword [[VB:v[0-9]+]], {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64 offset:4
14 ; GCN: v_mac_f32_e32 [[VB]], 0x41200000, [[VA]]
15 define amdgpu_kernel void @madmk_f32(float addrspace(1)* noalias %out, float addrspace(1)* noalias %in) nounwind {
16   %tid = tail call i32 @llvm.amdgcn.workitem.id.x() nounwind readnone
17   %gep.0 = getelementptr float, float addrspace(1)* %in, i32 %tid
18   %gep.1 = getelementptr float, float addrspace(1)* %gep.0, i32 1
19   %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
21   %a = load volatile float, float addrspace(1)* %gep.0, align 4
22   %b = load volatile float, float addrspace(1)* %gep.1, align 4
24   %mul = fmul float %a, 10.0
25   %madmk = fadd float %mul, %b
26   store float %madmk, float addrspace(1)* %out.gep, align 4
27   ret void
30 ; GCN-LABEL: {{^}}madmk_2_use_f32:
31 ; GCN-DAG: buffer_load_dword [[VA:v[0-9]+]], {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64{{$}}
32 ; GCN-DAG: buffer_load_dword [[VB:v[0-9]+]], {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64 offset:4
33 ; GCN-DAG: buffer_load_dword [[VC:v[0-9]+]], {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64 offset:8
34 ; GCN-DAG: v_mov_b32_e32 [[VK:v[0-9]+]], 0x41200000
35 ; GCN-DAG: v_mac_f32_e32 [[VB]], [[VA]], [[VK]]
36 ; GCN-DAG: v_mac_f32_e32 [[VC]], [[VA]], [[VK]]
37 ; GCN: s_endpgm
38 define amdgpu_kernel void @madmk_2_use_f32(float addrspace(1)* noalias %out, float addrspace(1)* noalias %in) nounwind {
39   %tid = tail call i32 @llvm.amdgcn.workitem.id.x() nounwind readnone
41   %in.gep.0 = getelementptr float, float addrspace(1)* %in, i32 %tid
42   %in.gep.1 = getelementptr float, float addrspace(1)* %in.gep.0, i32 1
43   %in.gep.2 = getelementptr float, float addrspace(1)* %in.gep.0, i32 2
45   %out.gep.0 = getelementptr float, float addrspace(1)* %out, i32 %tid
46   %out.gep.1 = getelementptr float, float addrspace(1)* %in.gep.0, i32 1
48   %a = load volatile float, float addrspace(1)* %in.gep.0, align 4
49   %b = load volatile float, float addrspace(1)* %in.gep.1, align 4
50   %c = load volatile float, float addrspace(1)* %in.gep.2, align 4
52   %mul0 = fmul float %a, 10.0
53   %mul1 = fmul float %a, 10.0
54   %madmk0 = fadd float %mul0, %b
55   %madmk1 = fadd float %mul1, %c
57   store float %madmk0, float addrspace(1)* %out.gep.0, align 4
58   store float %madmk1, float addrspace(1)* %out.gep.1, align 4
59   ret void
62 ; We don't get any benefit if the constant is an inline immediate.
63 ; GCN-LABEL: {{^}}madmk_inline_imm_f32:
64 ; GCN-DAG: buffer_load_dword [[VA:v[0-9]+]], {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64{{$}}
65 ; GCN-DAG: buffer_load_dword [[VB:v[0-9]+]], {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64 offset:4
66 ; GCN: v_mac_f32_e32 [[VB]], 4.0, [[VA]]
67 define amdgpu_kernel void @madmk_inline_imm_f32(float addrspace(1)* noalias %out, float addrspace(1)* noalias %in) nounwind {
68   %tid = tail call i32 @llvm.amdgcn.workitem.id.x() nounwind readnone
69   %gep.0 = getelementptr float, float addrspace(1)* %in, i32 %tid
70   %gep.1 = getelementptr float, float addrspace(1)* %gep.0, i32 1
71   %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
73   %a = load volatile float, float addrspace(1)* %gep.0, align 4
74   %b = load volatile float, float addrspace(1)* %gep.1, align 4
76   %mul = fmul float %a, 4.0
77   %madmk = fadd float %mul, %b
78   store float %madmk, float addrspace(1)* %out.gep, align 4
79   ret void
82 ; GCN-LABEL: {{^}}s_s_madmk_f32:
83 ; GCN-NOT: v_madmk_f32
84 ; GCN: v_mac_f32_e32
85 ; GCN: s_endpgm
86 define amdgpu_kernel void @s_s_madmk_f32(float addrspace(1)* noalias %out, float %a, float %b) nounwind {
87   %tid = tail call i32 @llvm.amdgcn.workitem.id.x() nounwind readnone
88   %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
90   %mul = fmul float %a, 10.0
91   %madmk = fadd float %mul, %b
92   store float %madmk, float addrspace(1)* %out.gep, align 4
93   ret void
96 ; GCN-LABEL: {{^}}v_s_madmk_f32:
97 ; GCN-NOT: v_madmk_f32
98 ; GCN: v_mad_f32
99 ; GCN: s_endpgm
100 define amdgpu_kernel void @v_s_madmk_f32(float addrspace(1)* noalias %out, float addrspace(1)* noalias %in, float %b) nounwind {
101   %tid = tail call i32 @llvm.amdgcn.workitem.id.x() nounwind readnone
102   %gep.0 = getelementptr float, float addrspace(1)* %in, i32 %tid
103   %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
104   %a = load float, float addrspace(1)* %gep.0, align 4
106   %mul = fmul float %a, 10.0
107   %madmk = fadd float %mul, %b
108   store float %madmk, float addrspace(1)* %out.gep, align 4
109   ret void
112 ; GCN-LABEL: {{^}}scalar_vector_madmk_f32:
113 ; GCN-NOT: v_madmk_f32
114 ; GCN: v_mac_f32_e32
115 ; GCN: s_endpgm
116 define amdgpu_kernel void @scalar_vector_madmk_f32(float addrspace(1)* noalias %out, float addrspace(1)* noalias %in, float %a) nounwind {
117   %tid = tail call i32 @llvm.amdgcn.workitem.id.x() nounwind readnone
118   %gep.0 = getelementptr float, float addrspace(1)* %in, i32 %tid
119   %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
120   %b = load float, float addrspace(1)* %gep.0, align 4
122   %mul = fmul float %a, 10.0
123   %madmk = fadd float %mul, %b
124   store float %madmk, float addrspace(1)* %out.gep, align 4
125   ret void
128 ; GCN-LABEL: {{^}}no_madmk_src0_modifier_f32:
129 ; GCN-DAG: buffer_load_dword [[VA:v[0-9]+]], {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64{{$}}
130 ; GCN-DAG: buffer_load_dword [[VB:v[0-9]+]], {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64 offset:4
131 ; GCN-DAG: v_mov_b32_e32 [[VK:v[0-9]+]], 0x41200000
132 ; GCN: v_mad_f32 {{v[0-9]+}}, |[[VA]]|, [[VK]], [[VB]]
133 define amdgpu_kernel void @no_madmk_src0_modifier_f32(float addrspace(1)* noalias %out, float addrspace(1)* noalias %in) nounwind {
134   %tid = tail call i32 @llvm.amdgcn.workitem.id.x() nounwind readnone
135   %gep.0 = getelementptr float, float addrspace(1)* %in, i32 %tid
136   %gep.1 = getelementptr float, float addrspace(1)* %gep.0, i32 1
137   %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
139   %a = load volatile float, float addrspace(1)* %gep.0, align 4
140   %b = load volatile float, float addrspace(1)* %gep.1, align 4
142   %a.fabs = call float @llvm.fabs.f32(float %a) nounwind readnone
144   %mul = fmul float %a.fabs, 10.0
145   %madmk = fadd float %mul, %b
146   store float %madmk, float addrspace(1)* %out.gep, align 4
147   ret void
150 ; GCN-LABEL: {{^}}no_madmk_src2_modifier_f32:
151 ; GCN-DAG: buffer_load_dword [[VA:v[0-9]+]], {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64{{$}}
152 ; GCN-DAG: buffer_load_dword [[VB:v[0-9]+]], {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64 offset:4
153 ; GCN: v_mad_f32 {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}, |{{[sv][0-9]+}}|
154 define amdgpu_kernel void @no_madmk_src2_modifier_f32(float addrspace(1)* noalias %out, float addrspace(1)* noalias %in) nounwind {
155   %tid = tail call i32 @llvm.amdgcn.workitem.id.x() nounwind readnone
156   %gep.0 = getelementptr float, float addrspace(1)* %in, i32 %tid
157   %gep.1 = getelementptr float, float addrspace(1)* %gep.0, i32 1
158   %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
160   %a = load volatile float, float addrspace(1)* %gep.0, align 4
161   %b = load volatile float, float addrspace(1)* %gep.1, align 4
163   %b.fabs = call float @llvm.fabs.f32(float %b) nounwind readnone
165   %mul = fmul float %a, 10.0
166   %madmk = fadd float %mul, %b.fabs
167   store float %madmk, float addrspace(1)* %out.gep, align 4
168   ret void
171 ; GCN-LABEL: {{^}}madmk_add_inline_imm_f32:
172 ; GCN: buffer_load_dword [[A:v[0-9]+]]
173 ; GCN: v_mov_b32_e32 [[VK:v[0-9]+]], 0x41200000
174 ; GCN: v_mad_f32 {{v[0-9]+}}, [[A]], [[VK]], 2.0
175 define amdgpu_kernel void @madmk_add_inline_imm_f32(float addrspace(1)* noalias %out, float addrspace(1)* noalias %in) nounwind {
176   %tid = tail call i32 @llvm.amdgcn.workitem.id.x() nounwind readnone
177   %gep.0 = getelementptr float, float addrspace(1)* %in, i32 %tid
178   %out.gep = getelementptr float, float addrspace(1)* %out, i32 %tid
180   %a = load float, float addrspace(1)* %gep.0, align 4
182   %mul = fmul float %a, 10.0
183   %madmk = fadd float %mul, 2.0
184   store float %madmk, float addrspace(1)* %out.gep, align 4
185   ret void
188 ; SI-LABEL: {{^}}kill_madmk_verifier_error:
189 ; SI: s_xor_b64
190 ; SI: v_mac_f32_e32 {{v[0-9]+}}, 0x472aee8c, {{v[0-9]+}}
191 ; SI: s_or_b64
192 define amdgpu_kernel void @kill_madmk_verifier_error() nounwind {
194   br label %bb2
196 bb1:                                              ; preds = %bb2
197   ret void
199 bb2:                                              ; preds = %bb6, %bb
200   %tmp = phi float [ undef, %bb ], [ %tmp8, %bb6 ]
201   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #1
202   %f_tid = bitcast i32 %tid to float
203   %tmp3 = fsub float %f_tid, %tmp
204   %tmp5 = fcmp oeq float %tmp3, 1.000000e+04
205   br i1 %tmp5, label %bb1, label %bb6
207 bb6:                                              ; preds = %bb2
208   %tmp4 = fmul float %tmp, undef
209   %tmp7 = fmul float %tmp4, 0x40E55DD180000000
210   %tmp8 = fadd float %tmp7, undef
211   br label %bb2
214 declare i32 @llvm.amdgcn.mbcnt.lo(i32, i32) #1
216 attributes #1 = { nounwind readnone }