spirv: fix emitting switch cases that directly jump to the merge block
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Thu, 3 Sep 2020 20:02:01 +0000 (22:02 +0200)
committerMarge Bot <eric+marge@anholt.net>
Fri, 4 Sep 2020 21:34:47 +0000 (21:34 +0000)
commit57fba85da408dd4ec98508b5106c156d616b5602
treec83bc0418a2f117390b61844e75b78f38ad493dc
parent11fbd9806dd99d7a18081ca0d09e4db977f8af1b
spirv: fix emitting switch cases that directly jump to the merge block

As shown in the valid SPIR-V below, if one switch case statement
directly jumps to the merge block, it has no branches at all and
we have to reset the fall variable. Otherwise, it creates an
unintentional fallthrough.

       OpSelectionMerge %97 None
       OpSwitch %96 %97 1 %99 2 %100
%100 = OpLabel
%102 = OpAccessChain %_ptr_StorageBuffer_v4float %86 %uint_0 %uint_37
%103 = OpLoad %v4float %102
%104 = OpBitcast %v4uint %103
%105 = OpCompositeExtract %uint %104 0
%106 = OpShiftLeftLogical %uint %105 %uint_1
       OpBranch %97
 %99 = OpLabel
       OpBranch %97
 %97 = OpLabel
%107 = OpPhi %uint %uint_4 %75 %uint_5 %99 %106 %100

This fixes serious corruption in Horizon Zero Dawn.

v2: Changed the code to skip the entire if-block instead of resetting
    the fallthrough variable.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3460
Cc: mesa-stable
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6590>
src/compiler/spirv/vtn_cfg.c