The piglit test shaders@ssa@fs-if-def-else-break fails with only with sb enabled but passes without it. The relevant parts of the failing shader before and after optimization look like this: ===== SHADER #12 ====================================== PS/BARTS/EVERGREEN ===== ===== 90 dw ===== 9 gprs ===== 2 stack ================================== [...] 0060 801f00fe 0100229c 6 MP x: PRED_SETNE_INT R8.x, PV.x, 0 0018 0000000b 82800000 JUMP @22 0020 0000001f a00c0000 ALU 4 @62 0062 000000f8 00200c90 7 x: MOV R1.x, 0 <---- 0064 000004f9 20200c90 y: MOV R1.y, 1.0 <---- 0066 000000f8 40200c90 z: MOV R1.z, 0 0068 800004f9 60200c90 w: MOV R1.w, 1.0 0022 0000000d 83400001 ELSE @26 POP:1 0024 00000023 a80c0000 ALU_POP_AFTER 4 @70 0070 000004f9 00200c90 8 x: MOV R1.x, 1.0 <---- 0072 000000f8 20200c90 y: MOV R1.y, 0 <---- 0074 000000f8 40200c90 z: MOV R1.z, 0 0076 800004f9 60200c90 w: MOV R1.w, 1.0 0026 40000027 a4040000 ALU_PUSH_BEFORE 2 @78 KC0[CB0:0-15] 0078 80000081 00801990 9 x: NOT_INT R4.x, KC0[1].x 0080 801f00fe 0100229c 10 MP x: PRED_SETNE_INT R8.x, PV.x, 0 0028 00000011 82800001 JUMP @34 POP:1 0030 00000011 82400000 LOOP_BREAK @34 0032 00000011 83800001 POP @34 POP:1 0034 00000002 81400000 LOOP_END @4 0036 00000029 a00c0000 ALU 4 @82 0082 00000001 00000c90 11 x: MOV R0.x, R1.x 0084 00000401 20000c90 y: MOV R0.y, R1.y 0086 00000801 40000c90 z: MOV R0.z, R1.z 0088 80000c01 60000c90 w: MOV R0.w, R1.w 0038 c0000000 95200688 EXPORT_DONE PIXEL 0 R0.xyzw EOP ===== SHADER_END =============================================================== ===== SHADER #12 OPT ================================== PS/BARTS/EVERGREEN ===== ===== 50 dw ===== 1 gprs ===== 2 stack ========================================= [...] 0040 801f0800 00002284 3 M x: PRED_SETNE_INT __.x, R0.z, 0 0018 0000000d 82800001 JUMP @26 POP:1 0020 00000015 a0040000 ALU 2 @42 0042 000000f9 00000c90 4 x: MOV R0.x, 1.0 <----- 0044 800000f8 20000c90 y: MOV R0.y, 0 <----- 0022 0000000e 82400000 LOOP_BREAK @28 0024 0000000d 83800001 POP @26 POP:1 0026 00000017 a0040000 ALU 2 @46 0046 000000f9 00000c90 5 x: MOV R0.x, 1.0 <----- 0048 800000f8 20000c90 y: MOV R0.y, 0 <----- 0028 00000002 81400000 LOOP_END @4 0030 c0000000 95200a44 EXPORT_DONE PIXEL 0 R0.0xy1 EOP ===== SHADER_END =============================================================== In short after the optimization R0.xy get the same values assigned in both decision paths. Best, Gert
Also shaders@ssa@fs-while-loop-rotate-value fails with sb enabled, but passes with nosb.
spec@glsl-1.10@execution@variable-indexing@ vs-output-array-float-index-wr vs-output-array-vec3-index-wr vs-output-array-vec4-index-wr also fail with sb enabled but pass without it.
Hello, I'm using an HD6310 graphic card and when I'm running piglit with mesa-17.3-rc5, I have the same error. What's the status of this bug ? Best regards, Romain Naour
After reviewing the byte code of fs-if-def-else-break I found that the problem is a bit different: In the original code BREAK is called in the loop when (KC0[0].x != 0) just like implemented in the glsl code: 0002 LOOP_START_DX10 @36 0004 ALU_PUSH_BEFORE 2 @48 KC0[CB0:0-15] 0048 2 x: MOV R2.x, 1 0050 3 MP x: PRED_SETNE_INT R6.x, KC0[0].x, 0 0006 JUMP @10 << JUMP is called if condition fails 0008 ALU 2 @52 0052 4 x: MOV R2.x, [0x00000002 2.8026e-45].x 0054 00000002 0010 ELSE @16 POP:1 0012 LOOP_BREAK @34 0014 POP @16 POP:1 however, in the optimized code the assignment and its branch is optimized away, and BREAK is called when (KC0[0].x == 0), i.e. exactly the opposite of the 0002 LOOP_START_DX10 @30 0004 PUSH @6 0006 ALU 1 @38 KC0[CB0:0-15] 0038 2 M x: PRED_SETNE_INT __.x, KC0[0].x, 0 0008 JUMP @14 POP:1 << JUMP is called if condition fails 0010 LOOP_BREAK @28 0012 POP @14 POP:1 i.e. the optimizer removed the if branch, keeps the else branch but acts as if it were the if branch, hence the failure.
With a bit more digging I found out that the sb optimizer simply drops the ELSE if no ALU instructions are found in the else branch, i.e. while(cond1) if (cond2) { a = b + c; } else { break; } } becomes while(cond1) if (cond2) { a = b + c; break; } } after the first sb/dce_cleanup pass, and this is obviously wrong. With the break in the if path this is not a problem. I'll attach two piglits that illustrate the behaviour.
Created attachment 136995 [details] Test that fails with r600/sb Other then in the fs-if-def-else-break piglit here the if path doesn't get completely optimized away.
Created attachment 136996 [details] Test that doesn't fail Here the break is in the if path and other then ELSE the JUMP instruction doesn't get optimized away. Since the ELSE clause contains an ALU clause it also doesn't get optimized away.
Should be resolved with commit 8d633f067b8a3d74e3f39faea0773a229d4b93b3 Author: Dave Airlie <airlied@redhat.com> Date: Tue Jan 30 16:38:51 2018 +1000 r600/sb: insert the else clause when we might depart from a loop
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.