llvm.org GIT mirror llvm / 7a1e317
AMDGPU: Add baseline test for mul24 ordering issues git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@369858 91177308-0d34-0410-b5e6-96231b3b80d8 Matt Arsenault 22 days ago
1 changed file(s) with 263 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -check-prefix=GFX9 %s
2
3 ; Make sure that AMDGPUCodeGenPrepare introduces mul24 intrinsics
4 ; after SLSR, as the intrinsics would interfere. It's unclear if these
5 ; should be introduced before LSR or not. It seems to help in some
6 ; cases, and hurt others.
7
8 define void @lsr_order_mul24_0(i32 %arg, i32 %arg2, i32 %arg6, i32 %arg13, i32 %arg16) #0 {
9 ; GFX9-LABEL: lsr_order_mul24_0:
10 ; GFX9: ; %bb.0: ; %bb
11 ; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
12 ; GFX9-NEXT: global_load_dword v5, v[0:1], off
13 ; GFX9-NEXT: v_and_b32_e32 v2, 0xffffff, v2
14 ; GFX9-NEXT: v_sub_u32_e32 v4, v4, v1
15 ; GFX9-NEXT: s_mov_b64 s[4:5], 0
16 ; GFX9-NEXT: s_waitcnt vmcnt(0)
17 ; GFX9-NEXT: ds_write_b32 v0, v5
18 ; GFX9-NEXT: BB0_1: ; %bb23
19 ; GFX9-NEXT: ; =>This Inner Loop Header: Depth=1
20 ; GFX9-NEXT: v_mul_u32_u24_e32 v5, v0, v2
21 ; GFX9-NEXT: v_add_u32_e32 v0, v0, v1
22 ; GFX9-NEXT: v_sub_u32_e32 v5, v4, v5
23 ; GFX9-NEXT: v_add_u32_e32 v5, v5, v0
24 ; GFX9-NEXT: v_cmp_ge_u32_e32 vcc, v5, v3
25 ; GFX9-NEXT: s_or_b64 s[4:5], vcc, s[4:5]
26 ; GFX9-NEXT: s_andn2_b64 exec, exec, s[4:5]
27 ; GFX9-NEXT: s_cbranch_execnz BB0_1
28 ; GFX9-NEXT: ; %bb.2: ; %.loopexit
29 ; GFX9-NEXT: s_or_b64 exec, exec, s[4:5]
30 ; GFX9-NEXT: s_waitcnt lgkmcnt(0)
31 ; GFX9-NEXT: s_setpc_b64 s[30:31]
32 bb:
33 %tmp22 = and i32 %arg6, 16777215
34 br label %bb23
35
36 .loopexit: ; preds = %bb23
37 ret void
38
39 bb23: ; preds = %bb23, %bb
40 %tmp24 = phi i32 [ %arg, %bb ], [ %tmp47, %bb23 ]
41 %tmp28 = and i32 %tmp24, 16777215
42 %tmp29 = mul i32 %tmp28, %tmp22
43 %tmp30 = sub i32 %tmp24, %tmp29
44 %tmp31 = add i32 %tmp30, %arg16
45 %tmp37 = icmp ult i32 %tmp31, %arg13
46 %tmp44 = load float, float addrspace(1)* undef, align 4
47 store float %tmp44, float addrspace(3)* undef, align 4
48 %tmp47 = add i32 %tmp24, %arg2
49 br i1 %tmp37, label %bb23, label %.loopexit
50 }
51
52 define void @lsr_order_mul24_1(i32 %arg, i32 %arg1, i32 %arg2, float addrspace(3)* nocapture %arg3, i32 %arg4, i32 %arg5, i32 %arg6, i32 %arg7, i32 %arg8, i32 %arg9, float addrspace(1)* nocapture readonly %arg10, i32 %arg11, i32 %arg12, i32 %arg13, i32 %arg14, i32 %arg15, i32 %arg16, i1 zeroext %arg17, i1 zeroext %arg18) #0 {
53 ; GFX9-LABEL: lsr_order_mul24_1:
54 ; GFX9: ; %bb.0: ; %bb
55 ; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
56 ; GFX9-NEXT: v_and_b32_e32 v5, 1, v18
57 ; GFX9-NEXT: v_cmp_eq_u32_e32 vcc, 1, v5
58 ; GFX9-NEXT: v_cmp_lt_u32_e64 s[4:5], v0, v1
59 ; GFX9-NEXT: s_and_saveexec_b64 s[10:11], s[4:5]
60 ; GFX9-NEXT: ; mask branch BB1_4
61 ; GFX9-NEXT: s_cbranch_execz BB1_4
62 ; GFX9-NEXT: BB1_1: ; %bb19
63 ; GFX9-NEXT: v_cvt_f32_u32_e32 v7, v6
64 ; GFX9-NEXT: v_and_b32_e32 v5, 0xffffff, v6
65 ; GFX9-NEXT: v_add_u32_e32 v6, v4, v0
66 ; GFX9-NEXT: v_lshl_add_u32 v3, v6, 2, v3
67 ; GFX9-NEXT: v_rcp_iflag_f32_e32 v4, v7
68 ; GFX9-NEXT: v_lshlrev_b32_e32 v6, 2, v2
69 ; GFX9-NEXT: v_add_u32_e32 v7, v17, v12
70 ; GFX9-NEXT: s_mov_b64 s[12:13], 0
71 ; GFX9-NEXT: BB1_2: ; %bb23
72 ; GFX9-NEXT: ; =>This Inner Loop Header: Depth=1
73 ; GFX9-NEXT: v_cvt_f32_u32_e32 v8, v0
74 ; GFX9-NEXT: v_add_u32_e32 v9, v17, v0
75 ; GFX9-NEXT: v_add_u32_e32 v12, v7, v0
76 ; GFX9-NEXT: v_add_u32_e32 v0, v0, v2
77 ; GFX9-NEXT: v_madak_f32 v8, v8, v4, 0x3727c5ac
78 ; GFX9-NEXT: v_cvt_u32_f32_e32 v8, v8
79 ; GFX9-NEXT: v_cmp_ge_u32_e64 s[4:5], v0, v1
80 ; GFX9-NEXT: v_mul_u32_u24_e32 v18, v8, v5
81 ; GFX9-NEXT: v_add_u32_e32 v8, v8, v16
82 ; GFX9-NEXT: v_cmp_lt_u32_e64 s[6:7], v8, v13
83 ; GFX9-NEXT: v_mul_lo_u32 v8, v8, v15
84 ; GFX9-NEXT: v_sub_u32_e32 v19, v9, v18
85 ; GFX9-NEXT: v_cmp_lt_u32_e64 s[8:9], v19, v14
86 ; GFX9-NEXT: s_and_b64 s[6:7], s[6:7], s[8:9]
87 ; GFX9-NEXT: v_sub_u32_e32 v12, v12, v18
88 ; GFX9-NEXT: s_and_b64 s[6:7], s[6:7], vcc
89 ; GFX9-NEXT: v_add_u32_e32 v8, v12, v8
90 ; GFX9-NEXT: v_mov_b32_e32 v9, 0
91 ; GFX9-NEXT: v_cndmask_b32_e64 v8, 0, v8, s[6:7]
92 ; GFX9-NEXT: v_lshlrev_b64 v[8:9], 2, v[8:9]
93 ; GFX9-NEXT: s_or_b64 s[12:13], s[4:5], s[12:13]
94 ; GFX9-NEXT: v_add_co_u32_e64 v8, s[4:5], v10, v8
95 ; GFX9-NEXT: v_addc_co_u32_e64 v9, s[4:5], v11, v9, s[4:5]
96 ; GFX9-NEXT: global_load_dword v8, v[8:9], off
97 ; GFX9-NEXT: s_waitcnt vmcnt(0)
98 ; GFX9-NEXT: v_cndmask_b32_e64 v8, 0, v8, s[6:7]
99 ; GFX9-NEXT: ds_write_b32 v3, v8
100 ; GFX9-NEXT: v_add_u32_e32 v3, v3, v6
101 ; GFX9-NEXT: s_andn2_b64 exec, exec, s[12:13]
102 ; GFX9-NEXT: s_cbranch_execnz BB1_2
103 ; GFX9-NEXT: ; %bb.3: ; %Flow
104 ; GFX9-NEXT: s_or_b64 exec, exec, s[12:13]
105 ; GFX9-NEXT: BB1_4: ; %Flow3
106 ; GFX9-NEXT: s_or_b64 exec, exec, s[10:11]
107 ; GFX9-NEXT: s_waitcnt lgkmcnt(0)
108 ; GFX9-NEXT: s_setpc_b64 s[30:31]
109 bb:
110 %tmp = icmp ult i32 %arg, %arg1
111 br i1 %tmp, label %bb19, label %.loopexit
112
113 bb19: ; preds = %bb
114 %tmp20 = uitofp i32 %arg6 to float
115 %tmp21 = fdiv float 1.000000e+00, %tmp20
116 %tmp22 = and i32 %arg6, 16777215
117 br label %bb23
118
119 .loopexit: ; preds = %bb23, %bb
120 ret void
121
122 bb23: ; preds = %bb19, %bb23
123 %tmp24 = phi i32 [ %arg, %bb19 ], [ %tmp47, %bb23 ]
124 %tmp25 = uitofp i32 %tmp24 to float
125 %tmp26 = tail call float @llvm.fmuladd.f32(float %tmp25, float %tmp21, float 0x3EE4F8B580000000) #2
126 %tmp27 = fptoui float %tmp26 to i32
127 %tmp28 = and i32 %tmp27, 16777215
128 %tmp29 = mul i32 %tmp28, %tmp22
129 %tmp30 = sub i32 %tmp24, %tmp29
130 %tmp31 = add i32 %tmp30, %arg16
131 %tmp32 = add i32 %tmp27, %arg15
132 %tmp33 = mul i32 %tmp32, %arg14
133 %tmp34 = add i32 %tmp33, %arg11
134 %tmp35 = add i32 %tmp34, %tmp31
135 %tmp36 = add i32 %tmp24, %arg4
136 %tmp37 = icmp ult i32 %tmp31, %arg13
137 %tmp38 = icmp ult i32 %tmp32, %arg12
138 %tmp39 = and i1 %tmp38, %tmp37
139 %tmp40 = and i1 %tmp39, %arg17
140 %tmp41 = zext i32 %tmp35 to i64
141 %tmp42 = select i1 %tmp40, i64 %tmp41, i64 0
142 %tmp43 = getelementptr inbounds float, float addrspace(1)* %arg10, i64 %tmp42
143 %tmp44 = load float, float addrspace(1)* %tmp43, align 4
144 %tmp45 = select i1 %tmp40, float %tmp44, float 0.000000e+00
145 %tmp46 = getelementptr inbounds float, float addrspace(3)* %arg3, i32 %tmp36
146 store float %tmp45, float addrspace(3)* %tmp46, align 4
147 %tmp47 = add i32 %tmp24, %arg2
148 %tmp48 = icmp ult i32 %tmp47, %arg1
149 br i1 %tmp48, label %bb23, label %.loopexit
150 }
151
152 define void @slsr1_0(i32 %b.arg, i32 %s.arg) #0 {
153 ; GFX9-LABEL: slsr1_0:
154 ; GFX9: ; %bb.0:
155 ; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
156 ; GFX9-NEXT: s_mov_b32 s4, 0xffffff
157 ; GFX9-NEXT: v_and_b32_e32 v2, s4, v0
158 ; GFX9-NEXT: v_and_b32_e32 v3, s4, v1
159 ; GFX9-NEXT: v_add_u32_e32 v2, 1, v2
160 ; GFX9-NEXT: v_mul_lo_u32 v2, v2, v3
161 ; GFX9-NEXT: v_mul_u32_u24_e32 v0, v0, v1
162 ; GFX9-NEXT: global_store_dword v[0:1], v0, off
163 ; GFX9-NEXT: global_store_dword v[0:1], v2, off
164 ; GFX9-NEXT: v_add_u32_e32 v0, v2, v3
165 ; GFX9-NEXT: global_store_dword v[0:1], v0, off
166 ; GFX9-NEXT: s_waitcnt vmcnt(0)
167 ; GFX9-NEXT: s_setpc_b64 s[30:31]
168 %b = and i32 %b.arg, 16777215
169 %s = and i32 %s.arg, 16777215
170
171 ; CHECK-LABEL: @slsr1(
172 ; foo(b * s);
173 %mul0 = mul i32 %b, %s
174 ; CHECK: mul i32
175 ; CHECK-NOT: mul i32
176 store volatile i32 %mul0, i32 addrspace(1)* undef
177
178 ; foo((b + 1) * s);
179 %b1 = add i32 %b, 1
180 %mul1 = mul i32 %b1, %s
181 store volatile i32 %mul1, i32 addrspace(1)* undef
182
183 ; foo((b + 2) * s);
184 %b2 = add i32 %b, 2
185 %mul2 = mul i32 %b2, %s
186 store volatile i32 %mul2, i32 addrspace(1)* undef
187 ret void
188 }
189
190 define void @slsr1_1(i32 %b.arg, i32 %s.arg) #0 {
191 ; GFX9-LABEL: slsr1_1:
192 ; GFX9: ; %bb.0:
193 ; GFX9-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
194 ; GFX9-NEXT: s_or_saveexec_b64 s[4:5], -1
195 ; GFX9-NEXT: buffer_store_dword v34, off, s[0:3], s32 offset:8 ; 4-byte Folded Spill
196 ; GFX9-NEXT: s_mov_b64 exec, s[4:5]
197 ; GFX9-NEXT: v_writelane_b32 v34, s34, 4
198 ; GFX9-NEXT: s_mov_b32 s34, s32
199 ; GFX9-NEXT: buffer_store_dword v32, off, s[0:3], s34 offset:4 ; 4-byte Folded Spill
200 ; GFX9-NEXT: buffer_store_dword v33, off, s[0:3], s34 ; 4-byte Folded Spill
201 ; GFX9-NEXT: v_writelane_b32 v34, s36, 0
202 ; GFX9-NEXT: s_mov_b32 s4, 0xffffff
203 ; GFX9-NEXT: s_add_u32 s32, s32, 0x400
204 ; GFX9-NEXT: v_writelane_b32 v34, s37, 1
205 ; GFX9-NEXT: v_and_b32_e32 v32, s4, v0
206 ; GFX9-NEXT: v_and_b32_e32 v33, s4, v1
207 ; GFX9-NEXT: s_getpc_b64 s[4:5]
208 ; GFX9-NEXT: s_add_u32 s4, s4, foo@gotpcrel32@lo+4
209 ; GFX9-NEXT: s_addc_u32 s5, s5, foo@gotpcrel32@hi+4
210 ; GFX9-NEXT: s_load_dwordx2 s[36:37], s[4:5], 0x0
211 ; GFX9-NEXT: v_writelane_b32 v34, s30, 2
212 ; GFX9-NEXT: v_mul_u32_u24_e32 v0, v0, v1
213 ; GFX9-NEXT: v_writelane_b32 v34, s31, 3
214 ; GFX9-NEXT: s_waitcnt lgkmcnt(0)
215 ; GFX9-NEXT: s_swappc_b64 s[30:31], s[36:37]
216 ; GFX9-NEXT: v_add_u32_e32 v0, 1, v32
217 ; GFX9-NEXT: v_mul_lo_u32 v32, v0, v33
218 ; GFX9-NEXT: v_mov_b32_e32 v0, v32
219 ; GFX9-NEXT: s_swappc_b64 s[30:31], s[36:37]
220 ; GFX9-NEXT: v_add_u32_e32 v0, v32, v33
221 ; GFX9-NEXT: s_swappc_b64 s[30:31], s[36:37]
222 ; GFX9-NEXT: v_readlane_b32 s4, v34, 2
223 ; GFX9-NEXT: v_readlane_b32 s5, v34, 3
224 ; GFX9-NEXT: v_readlane_b32 s37, v34, 1
225 ; GFX9-NEXT: v_readlane_b32 s36, v34, 0
226 ; GFX9-NEXT: buffer_load_dword v33, off, s[0:3], s34 ; 4-byte Folded Reload
227 ; GFX9-NEXT: buffer_load_dword v32, off, s[0:3], s34 offset:4 ; 4-byte Folded Reload
228 ; GFX9-NEXT: s_sub_u32 s32, s32, 0x400
229 ; GFX9-NEXT: v_readlane_b32 s34, v34, 4
230 ; GFX9-NEXT: s_or_saveexec_b64 s[6:7], -1
231 ; GFX9-NEXT: buffer_load_dword v34, off, s[0:3], s32 offset:8 ; 4-byte Folded Reload
232 ; GFX9-NEXT: s_mov_b64 exec, s[6:7]
233 ; GFX9-NEXT: s_waitcnt vmcnt(0)
234 ; GFX9-NEXT: s_setpc_b64 s[4:5]
235 %b = and i32 %b.arg, 16777215
236 %s = and i32 %s.arg, 16777215
237
238 ; CHECK-LABEL: @slsr1(
239 ; foo(b * s);
240 %mul0 = mul i32 %b, %s
241 ; CHECK: mul i32
242 ; CHECK-NOT: mul i32
243 call void @foo(i32 %mul0)
244
245 ; foo((b + 1) * s);
246 %b1 = add i32 %b, 1
247 %mul1 = mul i32 %b1, %s
248 call void @foo(i32 %mul1)
249
250 ; foo((b + 2) * s);
251 %b2 = add i32 %b, 2
252 %mul2 = mul i32 %b2, %s
253 call void @foo(i32 %mul2)
254
255 ret void
256 }
257
258 declare void @foo(i32) #0
259 declare float @llvm.fmuladd.f32(float, float, float) #1
260
261 attributes #0 = { nounwind willreturn }
262 attributes #1 = { nounwind readnone speculatable }