1 /* 2 * Copyright © 2020 Valve Corporation 3 * 4 * SPDX-License-Identifier: MIT 5 */ 6 #include <llvm/Config/llvm-config.h> 7 8 #include "helpers.h" 9 #include "test_isel-spirv.h" 10 11 using namespace aco; 12 13 BEGIN_TEST(isel.interp.simple) 14 QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX, 15 layout(location = 0) in vec4 in_color; 16 layout(location = 0) out vec4 out_color; 17 void main() { out_color = in_color; 18 } 19 ); 20 QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT, 21 layout(location = 0) in vec4 in_color; 22 layout(location = 0) out vec4 out_color; 23 void main() { 24 //>> v1: %b_tmp = v_interp_p1_f32 %bx, %pm:m0 attr0.z 25 //! v1: %b = v_interp_p2_f32 %by, %pm:m0, (kill)%b_tmp attr0.z 26 //! v1: %a_tmp = v_interp_p1_f32 %bx, %pm:m0 attr0.w 27 //! v1: %a = v_interp_p2_f32 %by, %pm:m0, (kill)%a_tmp attr0.w 28 //! v1: %r_tmp = v_interp_p1_f32 %bx, %pm:m0 attr0.x 29 //! v1: %r = v_interp_p2_f32 %by, %pm:m0, (kill)%r_tmp attr0.x 30 //! v1: %g_tmp = v_interp_p1_f32 (kill)%bx, %pm:m0 attr0.y 31 //! v1: %g = v_interp_p2_f32 (kill)%by, (kill)%pm:m0, (kill)%g_tmp attr0.y 32 //! exp (kill)%r, (kill)%g, (kill)%b, (kill)%a mrt0 33 out_color = in_color; 34 } 35 ); 36 37 PipelineBuilder pbld(get_vk_device(GFX9)); 38 pbld.add_vsfs(vs, fs); 39 pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "ACO IR"); 40 END_TEST 41 42 BEGIN_TEST(isel.compute.simple) 43 for (unsigned i = GFX7; i <= GFX8; i++) { 44 if (!set_variant((amd_gfx_level)i)) 45 continue; 46 47 QoShaderModuleCreateInfo cs = qoShaderModuleCreateInfoGLSL(COMPUTE, 48 layout(local_size_x=1) in; 49 layout(binding=0) buffer Buf { 50 uint res; 51 }; 52 void main() { 53 //>> v1: %data = p_parallelcopy 42 54 //! buffer_store_dword (kill)%_, v1: undef, 0, (kill)%data disable_wqm storage:buffer 55 res = 42; 56 } 57 ); 58 59 PipelineBuilder pbld(get_vk_device((amd_gfx_level)i)); 60 pbld.add_cs(cs); 61 pbld.print_ir(VK_SHADER_STAGE_COMPUTE_BIT, "ACO IR", true); 62 } 63 END_TEST 64 65 BEGIN_TEST(isel.gs.no_outputs) 66 for (unsigned i = GFX8; i <= GFX10; i++) { 67 if (!set_variant((amd_gfx_level)i)) 68 continue; 69 70 QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX, 71 void main() {} 72 ); 73 74 QoShaderModuleCreateInfo gs = qoShaderModuleCreateInfoGLSL(GEOMETRY, 75 layout(points) in; 76 layout(points, max_vertices = 1) out; 77 78 void main() { 79 EmitVertex(); 80 EndPrimitive(); 81 } 82 ); 83 84 PipelineBuilder pbld(get_vk_device((amd_gfx_level)i)); 85 pbld.add_stage(VK_SHADER_STAGE_VERTEX_BIT, vs); 86 pbld.add_stage(VK_SHADER_STAGE_GEOMETRY_BIT, gs); 87 pbld.create_pipeline(); 88 89 //! success 90 fprintf(output, "success\n"); 91 } 92 END_TEST 93 94 BEGIN_TEST(isel.gs.no_verts) 95 for (unsigned i = GFX8; i <= GFX10; i++) { 96 if (!set_variant((amd_gfx_level)i)) 97 continue; 98 99 QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX, 100 void main() {} 101 ); 102 103 QoShaderModuleCreateInfo gs = qoShaderModuleCreateInfoGLSL(GEOMETRY, 104 layout(points) in; 105 layout(points, max_vertices = 0) out; 106 107 void main() {} 108 ); 109 110 PipelineBuilder pbld(get_vk_device((amd_gfx_level)i)); 111 pbld.add_stage(VK_SHADER_STAGE_VERTEX_BIT, vs); 112 pbld.add_stage(VK_SHADER_STAGE_GEOMETRY_BIT, gs); 113 pbld.create_pipeline(); 114 115 //! success 116 fprintf(output, "success\n"); 117 } 118 END_TEST 119 120 BEGIN_TEST(isel.sparse.clause) 121 for (unsigned i = GFX10_3; i <= GFX10_3; i++) { 122 if (!set_variant((amd_gfx_level)i)) 123 continue; 124 125 QoShaderModuleCreateInfo cs = qoShaderModuleCreateInfoGLSL(COMPUTE, 126 QO_EXTENSION GL_ARB_sparse_texture2 : require 127 layout(local_size_x=1) in; 128 layout(binding=0) uniform sampler2D tex; 129 layout(binding=1) buffer Buf { 130 vec4 res[4]; 131 uint code[4]; 132 }; 133 void main() { 134 //>> v5: (noCSE)%zero0 = p_create_vector 0, 0, 0, 0, 0 135 //>> v5: %_ = image_sample_lz_o %_, %_, (kill)%zero0, (kill)%_, %_ dmask:xyzw 2d tfe a16 136 //>> v5: (noCSE)%zero1 = p_create_vector 0, 0, 0, 0, 0 137 //>> v5: %_ = image_sample_lz_o %_, %_, (kill)%zero1, (kill)%_, %_ dmask:xyzw 2d tfe a16 138 //>> v5: (noCSE)%zero2 = p_create_vector 0, 0, 0, 0, 0 139 //>> v5: %_ = image_sample_lz_o %_, %_, (kill)%zero2, (kill)%_, %_ dmask:xyzw 2d tfe a16 140 //>> v5: (noCSE)%zero3 = p_create_vector 0, 0, 0, 0, 0 141 //>> v5: %_ = image_sample_lz_o (kill)%_, (kill)%_, (kill)%zero3, (kill)%_, (kill)%_ dmask:xyzw 2d tfe a16 142 //>> s_clause 0x3 143 //! image_sample_lz_o v[#_:#_], v[#_:#_], @s256(img), @s128(samp) dmask:0xf dim:SQ_RSRC_IMG_2D a16 tfe 144 //! image_sample_lz_o v[#_:#_], [v#_, v#_], @s256(img), @s128(samp) dmask:0xf dim:SQ_RSRC_IMG_2D a16 tfe 145 //! image_sample_lz_o v[#_:#_], [v#_, v#_], @s256(img), @s128(samp) dmask:0xf dim:SQ_RSRC_IMG_2D a16 tfe 146 //! image_sample_lz_o v[#_:#_], [v#_, v#_], @s256(img), @s128(samp) dmask:0xf dim:SQ_RSRC_IMG_2D a16 tfe 147 code[0] = sparseTextureOffsetARB(tex, vec2(0.5), ivec2(1, 0), res[0]); 148 code[1] = sparseTextureOffsetARB(tex, vec2(0.5), ivec2(2, 0), res[1]); 149 code[2] = sparseTextureOffsetARB(tex, vec2(0.5), ivec2(3, 0), res[2]); 150 code[3] = sparseTextureOffsetARB(tex, vec2(0.5), ivec2(4, 0), res[3]); 151 } 152 ); 153 154 PipelineBuilder pbld(get_vk_device((amd_gfx_level)i)); 155 pbld.add_cs(cs); 156 pbld.print_ir(VK_SHADER_STAGE_COMPUTE_BIT, "ACO IR", true); 157 pbld.print_ir(VK_SHADER_STAGE_COMPUTE_BIT, "Assembly", true); 158 } 159 END_TEST 160 161 BEGIN_TEST(isel.discard_early_exit.mrtz) 162 QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX, 163 void main() {} 164 ); 165 QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT, 166 void main() { 167 if (gl_FragCoord.w > 0.5) 168 discard; 169 gl_FragDepth = 1.0 / gl_FragCoord.z; 170 } 171 ); 172 173 /* On GFX11, the discard early exit must use mrtz if the shader exports only depth. */ 174 //>> exp mrtz v#_, off, off, off done ; $_ $_ 175 //! s_nop 0 ; $_ 176 //! s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; $_ 177 //! s_endpgm ; $_ 178 //! BB1: 179 //! exp mrtz off, off, off, off done ; $_ $_ 180 //! s_nop 0 ; $_ 181 //! s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; $_ 182 //! s_endpgm ; $_ 183 184 PipelineBuilder pbld(get_vk_device(GFX11)); 185 pbld.add_vsfs(vs, fs); 186 pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "Assembly"); 187 END_TEST 188 189 BEGIN_TEST(isel.discard_early_exit.mrt0) 190 QoShaderModuleCreateInfo vs = qoShaderModuleCreateInfoGLSL(VERTEX, 191 void main() {} 192 ); 193 QoShaderModuleCreateInfo fs = qoShaderModuleCreateInfoGLSL(FRAGMENT, 194 layout(location = 0) out vec4 out_color; 195 void main() { 196 if (gl_FragCoord.w > 0.5) 197 discard; 198 out_color = vec4(1.0 / gl_FragCoord.z); 199 } 200 ); 201 202 /* On GFX11, the discard early exit must use mrt0 if the shader exports color. */ 203 //>> exp mrt0 v#x, v#x, v#x, v#x done ; $_ $_ 204 //! s_nop 0 ; $_ 205 //! s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; $_ 206 //! s_endpgm ; $_ 207 //! BB1: 208 //! exp mrt0 off, off, off, off done ; $_ $_ 209 //! s_nop 0 ; $_ 210 //! s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; $_ 211 //! s_endpgm ; $_ 212 213 PipelineBuilder pbld(get_vk_device(GFX11)); 214 pbld.add_vsfs(vs, fs); 215 pbld.print_ir(VK_SHADER_STAGE_FRAGMENT_BIT, "Assembly"); 216 END_TEST 217 218 BEGIN_TEST(isel.s_bfe_mask_bits) 219 QoShaderModuleCreateInfo cs = qoShaderModuleCreateInfoGLSL(COMPUTE, 220 layout(local_size_x=1) in; 221 layout(binding=0) buffer Buf { 222 int res; 223 }; 224 void main() { 225 //>> s1: %bits, s1: (kill)%_:scc = s_and_b32 (kill)%_, 31 226 //! s1: %src1 = s_pack_ll_b32_b16 0, (kill)%bits 227 //! s1: %_, s1: (kill)%_:scc = s_bfe_i32 0xdeadbeef, (kill)%src1 228 res = bitfieldExtract(0xdeadbeef, 0, res & 0x1f); 229 } 230 ); 231 232 PipelineBuilder pbld(get_vk_device(GFX10_3)); 233 pbld.add_cs(cs); 234 pbld.print_ir(VK_SHADER_STAGE_COMPUTE_BIT, "ACO IR", true); 235 END_TEST 236 237 /** 238 * loop { 239 * if (uniform) { 240 * break; 241 * } else { 242 * break; 243 * } 244 * // unreachable continue 245 * } 246 */ 247 BEGIN_TEST(isel.cf.unreachable_continue.uniform_break) 248 if (!setup_nir_cs(GFX11)) 249 return; 250 251 //>> s1: %init0 = p_unit_test 0 252 //>> v1: %init1 = p_unit_test 1 253 nir_def *init0 = nir_unit_test_uniform_amd(nb, 1, 32, .base=0); 254 nir_def *init1 = nir_unit_test_divergent_amd(nb, 1, 32, .base=1); 255 nir_phi_instr *phi[2]; 256 257 nir_loop *loop = nir_push_loop(nb); 258 { 259 //>> BB1 260 //! /* logical preds: BB0, / linear preds: BB0, / kind: uniform, loop-header, */ 261 //! v1: %_ = p_phi %init1 262 //! s1: %_ = p_linear_phi %init0 263 phi[0] = nir_phi_instr_create(nb->shader); 264 phi[1] = nir_phi_instr_create(nb->shader); 265 nir_def_init(&phi[0]->instr, &phi[0]->def, 1, 32); 266 nir_def_init(&phi[1]->instr, &phi[1]->def, 1, 32); 267 nir_phi_instr_add_src(phi[0], init0->parent_instr->block, init0); 268 nir_phi_instr_add_src(phi[1], init1->parent_instr->block, init1); 269 270 nir_push_if(nb, nir_unit_test_uniform_amd(nb, 1, 1, .base=4)); 271 { 272 //>> BB2 273 //! /* logical preds: BB1, / linear preds: BB1, / kind: uniform, break, */ 274 nir_jump(nb, nir_jump_break); 275 } 276 nir_push_else(nb, NULL); 277 { 278 /* The contents of this branch is moved to the merge block. */ 279 //>> BB3 280 //! /* logical preds: BB1, / linear preds: BB1, / kind: uniform, */ 281 //>> BB4 282 //! /* logical preds: BB3, / linear preds: BB3, / kind: uniform, break, */ 283 //! p_logical_start 284 //! s1: %_ = p_unit_test 5 285 //! p_logical_end 286 nir_unit_test_uniform_amd(nb, 1, 32, .base=5); 287 nir_jump(nb, nir_jump_break); 288 } 289 nir_pop_if(nb, NULL); 290 291 nir_def *cont0 = nir_unit_test_uniform_amd(nb, 1, 32, .base=2); 292 nir_def *cont1 = nir_unit_test_divergent_amd(nb, 1, 32, .base=3); 293 294 nir_phi_instr_add_src(phi[0], nir_loop_last_block(loop), cont0); 295 nir_phi_instr_add_src(phi[1], nir_loop_last_block(loop), cont1); 296 } 297 nir_pop_loop(nb, NULL); 298 299 nb->cursor = nir_after_phis(nir_loop_first_block(loop)); 300 nir_builder_instr_insert(nb, &phi[0]->instr); 301 nir_builder_instr_insert(nb, &phi[1]->instr); 302 nir_unit_test_amd(nb, &phi[0]->def); 303 nir_unit_test_amd(nb, &phi[1]->def); 304 305 finish_isel_test(); 306 END_TEST 307 308 /** 309 * loop { 310 * if (divergent) { 311 * break; 312 * } else { 313 * break; 314 * } 315 * // unreachable continue 316 * } 317 */ 318 BEGIN_TEST(isel.cf.unreachable_continue.divergent_break) 319 if (!setup_nir_cs(GFX11)) 320 return; 321 322 //>> s1: %init0 = p_unit_test 0 323 //>> v1: %init1 = p_unit_test 1 324 nir_def *init0 = nir_unit_test_uniform_amd(nb, 1, 32, .base=0); 325 nir_def *init1 = nir_unit_test_divergent_amd(nb, 1, 32, .base=1); 326 nir_phi_instr *phi[2]; 327 328 nir_loop *loop = nir_push_loop(nb); 329 { 330 //>> BB1 331 //! /* logical preds: BB0, / linear preds: BB0, / kind: loop-header, branch, */ 332 //! v1: %_ = p_phi %init1 333 //! s1: %_ = p_linear_phi %init0 334 phi[0] = nir_phi_instr_create(nb->shader); 335 phi[1] = nir_phi_instr_create(nb->shader); 336 nir_def_init(&phi[0]->instr, &phi[0]->def, 1, 32); 337 nir_def_init(&phi[1]->instr, &phi[1]->def, 1, 32); 338 nir_phi_instr_add_src(phi[0], init0->parent_instr->block, init0); 339 nir_phi_instr_add_src(phi[1], init1->parent_instr->block, init1); 340 341 nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base=4)); 342 { 343 //>> BB2 344 //! /* logical preds: BB1, / linear preds: BB1, / kind: break, */ 345 nir_jump(nb, nir_jump_break); 346 } 347 nir_push_else(nb, NULL); 348 { 349 /* The contents of this branch is moved to the merge block. */ 350 //>> BB7 351 //! /* logical preds: BB1, / linear preds: BB6, / kind: uniform, */ 352 //>> BB9 353 //! /* logical preds: BB7, / linear preds: BB7, BB8, / kind: uniform, break, merge, */ 354 //! p_logical_start 355 //! s1: %_ = p_unit_test 5 356 //! p_logical_end 357 nir_unit_test_uniform_amd(nb, 1, 32, .base=5); 358 nir_jump(nb, nir_jump_break); 359 } 360 nir_pop_if(nb, NULL); 361 362 nir_def *cont0 = nir_unit_test_uniform_amd(nb, 1, 32, .base=2); 363 nir_def *cont1 = nir_unit_test_divergent_amd(nb, 1, 32, .base=3); 364 365 nir_phi_instr_add_src(phi[0], nir_loop_last_block(loop), cont0); 366 nir_phi_instr_add_src(phi[1], nir_loop_last_block(loop), cont1); 367 } 368 nir_pop_loop(nb, NULL); 369 370 nb->cursor = nir_after_phis(nir_loop_first_block(loop)); 371 nir_builder_instr_insert(nb, &phi[0]->instr); 372 nir_builder_instr_insert(nb, &phi[1]->instr); 373 nir_unit_test_amd(nb, &phi[0]->def); 374 nir_unit_test_amd(nb, &phi[1]->def); 375 376 finish_isel_test(); 377 END_TEST 378 379 /** 380 * loop { 381 * if (uniform) { 382 * continue; 383 * } else { 384 * continue; 385 * } 386 * // unreachable block 387 * break; 388 * } 389 */ 390 BEGIN_TEST(isel.cf.unreachable_break.uniform_continue) 391 if (!setup_nir_cs(GFX11)) 392 return; 393 394 nir_def *val0; 395 nir_def *val1; 396 397 /* These are undefs. */ 398 //>> s3: %val1 = p_create_vector 0, 0, 0 399 //>> s1: %val0 = p_parallelcopy 0 400 401 nir_push_loop(nb); 402 { 403 //>> BB1 404 //! /* logical preds: BB0, BB2, BB7, / linear preds: BB0, BB2, BB7, / kind: uniform, loop-header, */ 405 nir_push_if(nb, nir_unit_test_uniform_amd(nb, 1, 1, .base=2)); 406 { 407 //>> BB2 408 //! /* logical preds: BB1, / linear preds: BB1, / kind: uniform, continue, */ 409 nir_jump(nb, nir_jump_continue); 410 } 411 nir_push_else(nb, NULL); 412 { 413 /* The contents of this branch is moved to the merge block, and a dummy break is inserted 414 * before the continue so that the loop has an exit. 415 */ 416 //>> BB3 417 //! /* logical preds: BB1, / linear preds: BB1, / kind: uniform, */ 418 //>> BB4 419 //! /* logical preds: BB3, / linear preds: BB3, / kind: uniform, */ 420 //! p_logical_start 421 //! s1: %_ = p_unit_test 5 422 //! s2: %zero = p_parallelcopy 0 423 //! s2: %_, s1: %cond:scc = s_and_b64 %zero, %0:exec 424 //! p_logical_end 425 //! s2: %_ = p_cbranch_z %cond:scc 426 //! BB5 427 //! /* logical preds: BB4, / linear preds: BB4, / kind: uniform, break, */ 428 //>> BB6 429 //! /* logical preds: BB4, / linear preds: BB4, / kind: uniform, */ 430 //>> BB7 431 //! /* logical preds: BB6, / linear preds: BB6, / kind: uniform, continue, */ 432 nir_unit_test_uniform_amd(nb, 1, 32, .base=5); 433 nir_jump(nb, nir_jump_continue); 434 } 435 nir_pop_if(nb, NULL); 436 437 val0 = nir_imm_zero(nb, 1, 32); 438 val1 = nir_load_local_invocation_id(nb); 439 440 nir_jump(nb, nir_jump_break); 441 } 442 nir_pop_loop(nb, NULL); 443 //>> BB8 444 //! /* logical preds: BB5, / linear preds: BB5, / kind: uniform, top-level, loop-exit, */ 445 446 //>> p_unit_test 0, %val0 447 //! p_unit_test 1, %val1 448 nir_unit_test_amd(nb, val0, .base=0); 449 nir_unit_test_amd(nb, val1, .base=1); 450 451 finish_isel_test(); 452 END_TEST 453 454 /** 455 * loop { 456 * if (uniform) { 457 * break; 458 * } else { 459 * if (divergent) { 460 * break; 461 * } else { 462 * break; 463 * } 464 * } 465 * // unreachable continue 466 * } 467 */ 468 BEGIN_TEST(isel.cf.unreachable_continue.mixed_break) 469 if (!setup_nir_cs(GFX11)) 470 return; 471 472 //>> s1: %init0 = p_unit_test 0 473 //>> v1: %init1 = p_unit_test 1 474 nir_def *init0 = nir_unit_test_uniform_amd(nb, 1, 32, .base=0); 475 nir_def *init1 = nir_unit_test_divergent_amd(nb, 1, 32, .base=1); 476 nir_phi_instr *phi[2]; 477 478 nir_loop *loop = nir_push_loop(nb); 479 { 480 //>> BB1 481 //! /* logical preds: BB0, / linear preds: BB0, / kind: uniform, loop-header, */ 482 //! v1: %_ = p_phi %init1 483 //! s1: %_ = p_linear_phi %init0 484 phi[0] = nir_phi_instr_create(nb->shader); 485 phi[1] = nir_phi_instr_create(nb->shader); 486 nir_def_init(&phi[0]->instr, &phi[0]->def, 1, 32); 487 nir_def_init(&phi[1]->instr, &phi[1]->def, 1, 32); 488 nir_phi_instr_add_src(phi[0], init0->parent_instr->block, init0); 489 nir_phi_instr_add_src(phi[1], init1->parent_instr->block, init1); 490 491 nir_push_if(nb, nir_unit_test_uniform_amd(nb, 1, 1, .base=4)); 492 { 493 //>> BB2 494 //! /* logical preds: BB1, / linear preds: BB1, / kind: uniform, break, */ 495 nir_jump(nb, nir_jump_break); 496 } 497 nir_push_else(nb, NULL); 498 { 499 /* The contents of this branch is moved to the merge block. */ 500 //>> BB3 501 //! /* logical preds: BB1, / linear preds: BB1, / kind: uniform, */ 502 //>> BB4 503 //! /* logical preds: BB3, / linear preds: BB3, / kind: branch, */ 504 //! p_logical_start 505 //! s2: %cond = p_unit_test 5 506 //! p_logical_end 507 //! s2: %_ = p_cbranch_z %cond 508 nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base=5)); 509 { 510 //>> BB5 511 //! /* logical preds: BB4, / linear preds: BB4, / kind: break, */ 512 nir_jump(nb, nir_jump_break); 513 } 514 nir_push_else(nb, NULL); 515 { 516 /* The contents of this branch is moved to the merge block. */ 517 //>> BB10 518 //! /* logical preds: BB4, / linear preds: BB9, / kind: uniform, */ 519 //>> BB12 520 //! /* logical preds: BB10, / linear preds: BB10, BB11, / kind: uniform, break, merge, */ 521 //! p_logical_start 522 //! s1: %_ = p_unit_test 6 523 nir_unit_test_uniform_amd(nb, 1, 32, .base=6); 524 nir_jump(nb, nir_jump_break); 525 } 526 nir_pop_if(nb, NULL); 527 } 528 nir_pop_if(nb, NULL); 529 530 nir_def *cont0 = nir_unit_test_uniform_amd(nb, 1, 32, .base=2); 531 nir_def *cont1 = nir_unit_test_divergent_amd(nb, 1, 32, .base=3); 532 533 nir_phi_instr_add_src(phi[0], nir_loop_last_block(loop), cont0); 534 nir_phi_instr_add_src(phi[1], nir_loop_last_block(loop), cont1); 535 } 536 nir_pop_loop(nb, NULL); 537 //>> BB13 538 //! /* logical preds: BB2, BB5, BB12, / linear preds: BB2, BB6, BB12, / kind: uniform, top-level, loop-exit, */ 539 540 nb->cursor = nir_after_phis(nir_loop_first_block(loop)); 541 nir_builder_instr_insert(nb, &phi[0]->instr); 542 nir_builder_instr_insert(nb, &phi[1]->instr); 543 nir_unit_test_amd(nb, &phi[0]->def); 544 nir_unit_test_amd(nb, &phi[1]->def); 545 546 finish_isel_test(); 547 END_TEST 548 549 /** 550 * loop { 551 * if (uniform) { 552 * break; 553 * } else { 554 * if (uniform) { 555 * break; 556 * } else { 557 * if (divergent) { 558 * break; 559 * } else { 560 * break; 561 * } 562 * } 563 * } 564 * // unreachable continue 565 * } 566 */ 567 BEGIN_TEST(isel.cf.unreachable_continue.nested_mixed_break) 568 if (!setup_nir_cs(GFX11)) 569 return; 570 571 //>> s1: %init0 = p_unit_test 0 572 //>> v1: %init1 = p_unit_test 1 573 nir_def *init0 = nir_unit_test_uniform_amd(nb, 1, 32, .base=0); 574 nir_def *init1 = nir_unit_test_divergent_amd(nb, 1, 32, .base=1); 575 nir_phi_instr *phi[2]; 576 577 nir_loop *loop = nir_push_loop(nb); 578 { 579 //>> BB1 580 //! /* logical preds: BB0, / linear preds: BB0, / kind: uniform, loop-header, */ 581 //! v1: %_ = p_phi %init1 582 //! s1: %_ = p_linear_phi %init0 583 phi[0] = nir_phi_instr_create(nb->shader); 584 phi[1] = nir_phi_instr_create(nb->shader); 585 nir_def_init(&phi[0]->instr, &phi[0]->def, 1, 32); 586 nir_def_init(&phi[1]->instr, &phi[1]->def, 1, 32); 587 nir_phi_instr_add_src(phi[0], init0->parent_instr->block, init0); 588 nir_phi_instr_add_src(phi[1], init1->parent_instr->block, init1); 589 590 nir_push_if(nb, nir_unit_test_uniform_amd(nb, 1, 1, .base=4)); 591 { 592 //>> BB2 593 //! /* logical preds: BB1, / linear preds: BB1, / kind: uniform, break, */ 594 nir_jump(nb, nir_jump_break); 595 } 596 nir_push_else(nb, NULL); 597 { 598 /* The contents of this branch is moved to the merge block. */ 599 //>> BB3 600 //! /* logical preds: BB1, / linear preds: BB1, / kind: uniform, */ 601 //>> BB4 602 //! /* logical preds: BB3, / linear preds: BB3, / kind: uniform, */ 603 //! p_logical_start 604 //! s2: %cond1 = p_unit_test 4 605 //! s2: %_, s1: %_:scc = s_and_b64 %cond1, %0:exec 606 //! p_logical_end 607 //! s2: %_ = p_cbranch_z %_:scc 608 nir_push_if(nb, nir_unit_test_uniform_amd(nb, 1, 1, .base=4)); 609 { 610 //>> BB5 611 //! /* logical preds: BB4, / linear preds: BB4, / kind: uniform, break, */ 612 nir_jump(nb, nir_jump_break); 613 } 614 nir_push_else(nb, NULL); 615 { 616 /* The contents of this branch is moved to the merge block. */ 617 //>> BB6 618 //! /* logical preds: BB4, / linear preds: BB4, / kind: uniform, */ 619 //>> BB7 620 //! /* logical preds: BB6, / linear preds: BB6, / kind: branch, */ 621 //! p_logical_start 622 //! s2: %cond2 = p_unit_test 5 623 //! p_logical_end 624 //! s2: %_ = p_cbranch_z %cond2 625 nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base=5)); 626 { 627 //>> BB8 628 //! /* logical preds: BB7, / linear preds: BB7, / kind: break, */ 629 nir_jump(nb, nir_jump_break); 630 } 631 nir_push_else(nb, NULL); 632 { 633 /* The contents of this branch is moved to the merge block. */ 634 //>> BB13 635 //! /* logical preds: BB7, / linear preds: BB12, / kind: uniform, */ 636 //>> BB15 637 //! /* logical preds: BB13, / linear preds: BB13, BB14, / kind: uniform, break, merge, */ 638 nir_jump(nb, nir_jump_break); 639 } 640 nir_pop_if(nb, NULL); 641 } 642 nir_pop_if(nb, NULL); 643 } 644 nir_pop_if(nb, NULL); 645 646 nir_def *cont0 = nir_unit_test_uniform_amd(nb, 1, 32, .base=2); 647 nir_def *cont1 = nir_unit_test_divergent_amd(nb, 1, 32, .base=3); 648 649 nir_phi_instr_add_src(phi[0], nir_loop_last_block(loop), cont0); 650 nir_phi_instr_add_src(phi[1], nir_loop_last_block(loop), cont1); 651 } 652 nir_pop_loop(nb, NULL); 653 654 nb->cursor = nir_after_phis(nir_loop_first_block(loop)); 655 nir_builder_instr_insert(nb, &phi[0]->instr); 656 nir_builder_instr_insert(nb, &phi[1]->instr); 657 nir_unit_test_amd(nb, &phi[0]->def); 658 nir_unit_test_amd(nb, &phi[1]->def); 659 660 finish_isel_test(); 661 END_TEST 662 663 /** 664 * loop { 665 * continue; 666 * } 667 */ 668 BEGIN_TEST(isel.cf.unreachable_loop_exit) 669 if (!setup_nir_cs(GFX11)) 670 return; 671 672 nir_push_loop(nb); 673 { 674 /* A dummy break is inserted before the continue so that the loop has an exit. */ 675 //>> BB1 676 //! /* logical preds: BB0, BB4, / linear preds: BB0, BB4, / kind: uniform, loop-header, */ 677 //>> s1: %_ = p_unit_test 0 678 //>> s2: %zero = p_parallelcopy 0 679 //>> s2: %_, s1: %cond:scc = s_and_b64 %zero, %0:exec 680 //>> s2: %_ = p_cbranch_z %cond:scc 681 //! BB2 682 //! /* logical preds: BB1, / linear preds: BB1, / kind: uniform, break, */ 683 //>> BB4 684 //! /* logical preds: BB3, / linear preds: BB3, / kind: uniform, continue, */ 685 nir_unit_test_uniform_amd(nb, 1, 32, .base=0); 686 nir_jump(nb, nir_jump_continue); 687 } 688 nir_pop_loop(nb, NULL); 689 690 finish_isel_test(); 691 END_TEST 692 693 /** 694 * loop { 695 * if (divergent) { 696 * break; 697 * } else { 698 * val = uniform; 699 * } 700 * use(val); 701 * } 702 */ 703 BEGIN_TEST(isel.cf.divergent_if_branch_use) 704 if (!setup_nir_cs(GFX11)) 705 return; 706 707 nir_push_loop(nb); 708 { 709 nir_def *val; 710 nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base=2)); 711 { 712 //>> BB2 713 //! /* logical preds: BB1, / linear preds: BB1, / kind: break, */ 714 nir_jump(nb, nir_jump_break); 715 } 716 nir_push_else(nb, NULL); 717 { 718 /* The contents of this branch is moved to the merge block. */ 719 //>> BB9 720 //! /* logical preds: BB7, / linear preds: BB7, BB8, / kind: uniform, continue, merge, */ 721 //! p_logical_start 722 //! s1: %val = p_unit_test 0 723 val = nir_unit_test_uniform_amd(nb, 1, 32, .base=0); 724 } 725 nir_pop_if(nb, NULL); 726 727 //! p_unit_test 1, %val 728 nir_unit_test_amd(nb, val, .base=1); 729 } 730 nir_pop_loop(nb, NULL); 731 732 finish_isel_test(); 733 END_TEST 734 735 /** 736 * loop { 737 * if (divergent) { 738 * continue; 739 * } 740 * if (uniform) { 741 * break; 742 * } else { 743 * val = uniform; 744 * } 745 * use(val); 746 * } 747 */ 748 BEGIN_TEST(isel.cf.uniform_if_branch_use) 749 if (!setup_nir_cs(GFX11)) 750 return; 751 752 nir_push_loop(nb); 753 { 754 nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base=3)); 755 { 756 nir_jump(nb, nir_jump_continue); 757 } 758 nir_pop_if(nb, NULL); 759 760 //>> s2: %cond = p_unit_test 2 761 //! s2: %_, s1: %_:scc = s_and_b64 %cond, %0:exec 762 //! p_logical_end 763 //! s2: %_ = p_cbranch_z %_:scc 764 nir_def *val; 765 nir_push_if(nb, nir_unit_test_uniform_amd(nb, 1, 1, .base=2)); 766 { 767 //>> BB10 768 //! /* logical preds: BB9, / linear preds: BB9, / kind: break, */ 769 nir_jump(nb, nir_jump_break); 770 } 771 nir_push_else(nb, NULL); 772 { 773 /* The contents of this branch is moved to the merge block. */ 774 //>> BB14 775 //! /* logical preds: BB13, / linear preds: BB12, BB13, / kind: uniform, continue, */ 776 //! p_logical_start 777 //! s1: %val = p_unit_test 0 778 val = nir_unit_test_uniform_amd(nb, 1, 32, .base=0); 779 } 780 nir_pop_if(nb, NULL); 781 782 //! p_unit_test 1, %val 783 nir_unit_test_amd(nb, val, .base=1); 784 } 785 nir_pop_loop(nb, NULL); 786 787 finish_isel_test(); 788 END_TEST 789 790 /** 791 * b = ... 792 * loop { 793 * a = linear_phi b, c, d 794 * if (divergent) { 795 * c = ... 796 * continue 797 * } 798 * d = c or undef 799 * break 800 * } 801 */ 802 BEGIN_TEST(isel.cf.hidden_continue) 803 if (!setup_nir_cs(GFX11)) 804 return; 805 806 //>> s1: %init = p_unit_test 0 807 nir_def* init = nir_unit_test_uniform_amd(nb, 1, 32, .base = 0); 808 nir_phi_instr* phi; 809 810 nir_loop* loop = nir_push_loop(nb); 811 { 812 //>> BB1 813 //! /* logical preds: BB0, BB2, / linear preds: BB0, BB3, BB11, / kind: loop-header, branch, */ 814 //! s1: %2 = p_linear_phi %init, %cont, %phi 815 phi = nir_phi_instr_create(nb->shader); 816 nir_def_init(&phi->instr, &phi->def, 1, 32); 817 nir_phi_instr_add_src(phi, init->parent_instr->block, init); 818 819 nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 4)); 820 { 821 //>> BB2 822 //! /* logical preds: BB1, / linear preds: BB1, / kind: continue, */ 823 //! p_logical_start 824 //! s1: %cont = p_unit_test 1 825 nir_def* cont = nir_unit_test_uniform_amd(nb, 1, 32, .base = 1); 826 nir_phi_instr_add_src(phi, cont->parent_instr->block, cont); 827 nir_jump(nb, nir_jump_continue); 828 } 829 nir_pop_if(nb, NULL); 830 //>> BB6 831 //! /* logical preds: / linear preds: BB4, BB5, / kind: invert, */ 832 //! s1: %phi = p_linear_phi %cont, s1: undef 833 834 //>> BB9 835 //! /* logical preds: BB7, / linear preds: BB7, BB8, / kind: break, merge, */ 836 //>> BB11 837 //! /* logical preds: / linear preds: BB9, / kind: uniform, continue, */ 838 nir_jump(nb, nir_jump_break); 839 } 840 nir_pop_loop(nb, NULL); 841 842 nb->cursor = nir_after_phis(nir_loop_first_block(loop)); 843 nir_builder_instr_insert(nb, &phi->instr); 844 nir_unit_test_amd(nb, &phi->def); 845 846 finish_isel_test(); 847 END_TEST 848 849 /** 850 * a = ... 851 * loop { 852 * if (uniform) { 853 * break 854 * } 855 * discard_if 856 * } 857 * b = phi a 858 */ 859 BEGIN_TEST(isel.cf.hidden_break) 860 if (!setup_nir_cs(GFX11)) 861 return; 862 863 //>> s1: %brk = p_unit_test 0 864 nir_def* brk = nir_unit_test_uniform_amd(nb, 1, 32, .base = 0); 865 nir_block* block; 866 nir_push_loop(nb); 867 { 868 nir_push_if(nb, nir_unit_test_uniform_amd(nb, 1, 1, .base = 4)); 869 { 870 block = nir_cursor_current_block(nb->cursor); 871 nir_jump(nb, nir_jump_break); 872 } 873 nir_pop_if(nb, NULL); 874 //>> BB4 875 //! /* logical preds: BB3, / linear preds: BB3, / kind: uniform, continue_or_break, discard, */ 876 877 nir_discard_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 5)); 878 } 879 nir_pop_loop(nb, NULL); 880 881 //>> BB7 882 //! /* logical preds: BB2, / linear preds: BB2, BB5, / kind: uniform, top-level, loop-exit, */ 883 //! s1: %4 = p_linear_phi %1, s1: undef 884 nir_phi_instr* phi = nir_phi_instr_create(nb->shader); 885 nir_def_init(&phi->instr, &phi->def, 1, 32); 886 nir_phi_instr_add_src(phi, block, brk); 887 nir_builder_instr_insert(nb, &phi->instr); 888 nir_unit_test_amd(nb, &phi->def); 889 890 finish_isel_test(); 891 END_TEST 892 893 /** 894 * loop { 895 * if (divergent) { 896 * a = loop_invariant_sgpr 897 * break 898 * } 899 * discard_if 900 * } 901 * use(a) 902 */ 903 BEGIN_TEST(isel.cf.hidden_break_no_lcssa) 904 if (!setup_nir_cs(GFX11)) 905 return; 906 907 nir_def* val; 908 nir_push_loop(nb); 909 { 910 //>> BB1 911 //! /* logical preds: BB0, BB9, / linear preds: BB0, BB11, / kind: loop-header, branch, */ 912 //! s1: %val_header_phi = p_linear_phi s1: undef, %val_invert_phi 913 914 nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 1)); 915 { 916 //>> BB2 917 //! /* logical preds: BB1, / linear preds: BB1, / kind: break, */ 918 //! p_logical_start 919 //! s1: %val = p_parallelcopy 0 920 val = nir_imm_zero(nb, 1, 32); 921 nir_jump(nb, nir_jump_break); 922 } 923 nir_pop_if(nb, NULL); 924 925 //>> BB6 926 //! /* logical preds: / linear preds: BB4, BB5, / kind: invert, */ 927 //! s1: %val_invert_phi = p_linear_phi %val, %val_header_phi 928 //>> BB9 929 //! /* logical preds: BB7, / linear preds: BB7, BB8, / kind: uniform, continue_or_break, merge, discard, */ 930 nir_discard_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 2)); 931 } 932 nir_pop_loop(nb, NULL); 933 934 //>> BB12 935 //! /* logical preds: BB2, / linear preds: BB3, BB10, / kind: uniform, top-level, loop-exit, */ 936 //! s1: %val_exit_phi = p_linear_phi %val, %val_invert_phi 937 //! p_logical_start 938 //! p_unit_test 0, %val_exit_phi 939 nir_unit_test_amd(nb, val, .base = 0); 940 941 finish_isel_test(); 942 END_TEST 943 944 /** 945 * loop { 946 * use(phi(, a)) 947 * discard_if 948 * loop { 949 * if (uniform) { 950 * a = loop_invariant_sgpr 951 * break 952 * } 953 * } 954 * } 955 */ 956 BEGIN_TEST(isel.cf.hidden_break_no_lcssa_header_phi) 957 if (!setup_nir_cs(GFX11)) 958 return; 959 960 //>> p_startpgm 961 //! p_logical_start 962 //! s1: %init = p_unit_test 0 963 nir_def* init = nir_unit_test_uniform_amd(nb, 1, 32, .base = 0); 964 965 nir_def* val; 966 nir_phi_instr* phi; 967 nir_loop *loop = nir_push_loop(nb); 968 { 969 //>> BB1 970 //! /* logical preds: BB0, BB11, / linear preds: BB0, BB13, / kind: uniform, loop-preheader, loop-header, discard, */ 971 //! s1: %phi = p_linear_phi %init, %val_lcssa 972 //! p_logical_start 973 //! p_unit_test 1, %phi 974 phi = nir_phi_instr_create(nb->shader); 975 nir_def_init(&phi->instr, &phi->def, 1, 32); 976 nir_phi_instr_add_src(phi, init->parent_instr->block, init); 977 nir_unit_test_amd(nb, &phi->def, .base = 1); 978 979 nir_discard_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 2)); 980 981 //>> BB2 982 //! /* logical preds: BB1, BB5, / linear preds: BB1, BB7, / kind: uniform, loop-header, */ 983 nir_push_loop(nb); 984 { 985 nir_push_if(nb, nir_unit_test_uniform_amd(nb, 1, 1, .base = 3)); 986 { 987 //>> BB3 988 //! /* logical preds: BB2, / linear preds: BB2, / kind: uniform, break, */ 989 //! p_logical_start 990 //! s1: %val = p_parallelcopy 0 991 val = nir_imm_zero(nb, 1, 32); 992 nir_jump(nb, nir_jump_break); 993 } 994 nir_pop_if(nb, NULL); 995 //>> BB5 996 //! /* logical preds: BB4, / linear preds: BB4, / kind: uniform, continue_or_break, */ 997 } 998 nir_pop_loop(nb, NULL); 999 //>> BB8 1000 //! /* logical preds: BB3, / linear preds: BB3, BB6, / kind: uniform, loop-exit, */ 1001 //! s1: %val_lcssa = p_linear_phi %val, s1: undef 1002 //>> BB11 1003 //! /* logical preds: BB10, / linear preds: BB10, / kind: uniform, continue_or_break, */ 1004 1005 nir_phi_instr_add_src(phi, nir_cursor_current_block(nb->cursor), val); 1006 } 1007 nir_pop_loop(nb, NULL); 1008 1009 nb->cursor = nir_after_phis(nir_loop_first_block(loop)); 1010 nir_builder_instr_insert(nb, &phi->instr); 1011 1012 finish_isel_test(); 1013 END_TEST 1014 1015 /** 1016 * if (divergent) { 1017 * a = 1018 * } else { 1019 * } 1020 * b = phi(a, undef); 1021 * } 1022 */ 1023 BEGIN_TEST(isel.cf.divergent_if_undef.basic_then) 1024 if (!setup_nir_cs(GFX11)) 1025 return; 1026 1027 nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 2)); 1028 //>> BB1 1029 //! /* logical preds: BB0, / linear preds: BB0, / kind: uniform, */ 1030 //! p_logical_start 1031 //! s1: %val = p_unit_test 0 1032 nir_def* val = nir_unit_test_uniform_amd(nb, 1, 32, .base = 0); 1033 nir_pop_if(nb, NULL); 1034 1035 //>> BB3 1036 //! /* logical preds: / linear preds: BB1, BB2, / kind: invert, */ 1037 //! s1: %phi = p_linear_phi %val, s1: undef 1038 //>> BB6 1039 //! /* logical preds: BB1, BB4, / linear preds: BB4, BB5, / kind: uniform, top-level, merge, */ 1040 //! s1: %phi2 = p_linear_phi %phi, %phi 1041 //! p_logical_start 1042 //! p_unit_test 1, %phi2 1043 nir_unit_test_amd(nb, nir_if_phi(nb, val, nir_undef(nb, 1, 32)), .base = 1); 1044 1045 finish_isel_test(); 1046 END_TEST 1047 1048 /** 1049 * if (divergent) { 1050 * } else { 1051 * a = 1052 * } 1053 * b = phi(undef, a); 1054 * } 1055 */ 1056 BEGIN_TEST(isel.cf.divergent_if_undef.basic_else) 1057 if (!setup_nir_cs(GFX11)) 1058 return; 1059 1060 nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 2)); 1061 nir_push_else(nb, NULL); 1062 //>> BB3 1063 //! /* logical preds: / linear preds: BB1, BB2, / kind: invert, */ 1064 //>> BB4 1065 //! /* logical preds: BB0, / linear preds: BB3, / kind: uniform, */ 1066 //! p_logical_start 1067 //! s1: %val = p_unit_test 0 1068 nir_def* val = nir_unit_test_uniform_amd(nb, 1, 32, .base = 0); 1069 nir_pop_if(nb, NULL); 1070 1071 //>> BB6 1072 //! /* logical preds: BB1, BB4, / linear preds: BB4, BB5, / kind: uniform, top-level, merge, */ 1073 //! s1: %phi = p_linear_phi %val, s1: undef 1074 //! p_logical_start 1075 //! p_unit_test 1, %phi 1076 nir_unit_test_amd(nb, nir_if_phi(nb, nir_undef(nb, 1, 32), val), .base = 1); 1077 1078 finish_isel_test(); 1079 END_TEST 1080 1081 /** 1082 * loop { 1083 * a = 1084 * if (divergent) { 1085 * break; 1086 * } else { 1087 * } 1088 * b = phi(a); 1089 * } 1090 */ 1091 BEGIN_TEST(isel.cf.divergent_if_undef.break) 1092 if (!setup_nir_cs(GFX11)) 1093 return; 1094 1095 nir_push_loop(nb); 1096 { 1097 //>> BB1 1098 //! /* logical preds: BB0, BB9, / linear preds: BB0, BB9, / kind: loop-header, branch, */ 1099 //! p_logical_start 1100 //! s1: %val = p_unit_test 0 1101 //! s2: %_ = p_unit_test 2 1102 nir_def* val = nir_unit_test_uniform_amd(nb, 1, 32, .base = 0); 1103 nir_if* nif = nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 2)); 1104 { 1105 //>> BB2 1106 //! /* logical preds: BB1, / linear preds: BB1, / kind: break, */ 1107 nir_jump(nb, nir_jump_break); 1108 } 1109 nir_push_else(nb, NULL); 1110 {} 1111 nir_pop_if(nb, NULL); 1112 1113 //>> BB9 1114 //! /* logical preds: BB7, / linear preds: BB7, BB8, / kind: uniform, continue, merge, */ 1115 //! s1: %phi = p_linear_phi %val, s1: undef 1116 nir_phi_instr* phi = nir_phi_instr_create(nb->shader); 1117 nir_phi_instr_add_src(phi, nir_if_last_else_block(nif), val); 1118 nir_def_init(&phi->instr, &phi->def, 1, 32); 1119 nir_builder_instr_insert(nb, &phi->instr); 1120 1121 //! p_logical_start 1122 //! p_unit_test 1, %phi 1123 nir_unit_test_amd(nb, &phi->def, .base = 1); 1124 } 1125 nir_pop_loop(nb, NULL); 1126 1127 finish_isel_test(); 1128 END_TEST 1129 1130 /** 1131 * if (divergent) { 1132 * } else { 1133 * } 1134 * a = phi(undef, undef); 1135 * } 1136 */ 1137 BEGIN_TEST(isel.cf.divergent_if_undef.both) 1138 if (!setup_nir_cs(GFX11)) 1139 return; 1140 1141 nir_push_if(nb, nir_unit_test_divergent_amd(nb, 1, 1, .base = 1)); 1142 nir_pop_if(nb, NULL); 1143 //>> BB6 1144 //! /* logical preds: BB1, BB4, / linear preds: BB4, BB5, / kind: uniform, top-level, merge, */ 1145 //! s1: %4 = p_linear_phi s1: undef, s1: undef 1146 nir_unit_test_amd(nb, nir_if_phi(nb, nir_undef(nb, 1, 32), nir_undef(nb, 1, 32)), .base = 0); 1147 1148 finish_isel_test(); 1149 END_TEST 1150