nir/opt_if: Fix undef handling in opt_split_alu_of_phi()
authorConnor Abbott <cwabbott0@gmail.com>
Wed, 28 Aug 2019 14:56:57 +0000 (16:56 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 18 Sep 2019 21:18:34 +0000 (17:18 -0400)
commit57e0bb8ccc81ece56fd3081cb9a282b088124c6e
tree33102ee95dfc8746dc7e8c1b24e698f19442f72b
parenta1de3011f380b6ffd5583708b58e3f86d8d45ea9
nir/opt_if: Fix undef handling in opt_split_alu_of_phi()

The pass assumed that "Most ALU ops produce an undefined result if any
source is undef" which is completely untrue. Due to how we lower if
statements to selects and then optimize on those selects later, we
simply cannot make that assumption. In particular this pass tried to
replace an ior of undef and true, which had been generated by
optimizing a select which itself came from flattening an if statement,
to undef causing a miscompilation for a CTS test with radeonsi NIR.

We fix this by always doing what the non-undef path did, i.e. duplicate
the instruction twice. If there are cases where the instruction before
the loop can be folded away due to having an undef source, we should add
these to opt_undef instead.

The comment above the pass says that if the phi source from before the
loop is undef, and we can fold the instruction before the loop to undef,
then we can ignore sources of the original instruction that don't
dominate the block before the loop because we don't need them to create
the instruction before the loop. This is incorrect, because the
instruction at the bottom of the loop would get those sources from the
wrong loop iteration. The code never actually did what the comment said,
so we only have to update the comment to match what the pass actually
does. We also update the example to more closely match what most actual
loops look like after vtn and peephole_select.

There are no shader-db changes with i965, radeonsi NIR, or radv. With
anv and my vkpipeline-db there's only one change:

total instructions in shared programs: 14125290 -> 14125300 (<.01%)
instructions in affected programs: 2598 -> 2608 (0.38%)
helped: 0
HURT: 1

total cycles in shared programs: 2051473437 -> 2051473397 (<.01%)
cycles in affected programs: 36697 -> 36657 (-0.11%)
helped: 1
HURT: 0

Fixes
KHR-GL45.shader_subroutine.control_flow_and_returned_subroutine_values_used_as_subroutine_input
with radeonsi NIR.
src/compiler/nir/nir_opt_if.c