Skip to content

nir: Teach nir_opt_preamble about control flow

Alyssa Rosenzweig requested to merge alyssa/mesa:nir/preamble-ifs into main

Currently, nir_opt_preamble just looks at instructions locally and ignores the global CFG. This means that it behaves unsoundly on some shaders, e.g. it will hoist a load out of a bounds check. See #8649 (closed) for background. Simply refusing to hoist from control flow is a big shader-db hit, however. Instead, we need to make nir_opt_preamble aware of the control flow so it can act accordingly. To this end, this series arms nir_opt_preamble with two new tricks:

  1. a new ACCESS_CAN_SPECULATE flag. Often the driver knows it's safe to hoist a load out of control flow (e.g. due to hardware bounds checking), even though nir_opt_preamble doesn't know that. The solution is to augment loads with a speculate? flag which drivers can set based on their needs, so that nir_opt_preamble can continue to speculate loads when it's safe to do so. This is more nuanced than a "bool can_speculate_loads" pass option. For example, nir_lower_robust_access could set CAN_SPECULATE on any loads for which it clamped the input into bounds. It also makes this information available to other NIR passes, particularly nir_opt_peephole_select, giving a sound way forward for !8299 (merged).
  2. the ability to reconstruct (possibly nested) uniform if-else statements. Even if we can't speculate a load, if the load is inside an if-statement with a can_move condition, we can reconstruct the entire if-statement in the preamble and only do the load inside the if.

As a bonus, once all the infrastructure is in place for reconstructing if statements, it's fairly straightforward to move phis into the preamble. So that gives a nice win on some shaders.

Edited by Alyssa Rosenzweig

Merge request reports