10 Commits

Author SHA1 Message Date
joaosaffran
380bb51b70
[HLSL] Adding Flatten and Branch if attributes with test fixes (#122157)
- Adding the changes from PRs: 
  - #116331 
  - #121852 
- Fixes test `tools/dxil-dis/debug-info.ll`
- Address some missed comments in the previous PR

---------

Co-authored-by: joaosaffran <joao.saffran@microsoft.com>
2025-01-13 10:31:25 -08:00
Chris B
b66f6b25cb
Revert #116331 & #121852 (#122105) 2025-01-08 08:55:02 -06:00
joaosaffran
0d5c07285f
[HLSL] Adding Flatten and Branch if attributes (#116331)
- adding Flatten and Branch to if stmt.
- adding dxil control flow hint metadata generation
- modifing spirv OpSelectMerge to account for the specific attributes.

Closes #70112

---------

Co-authored-by: Joao Saffran <jderezende@microsoft.com>
Co-authored-by: joaosaffran <joao.saffran@microsoft.com>
2025-01-06 10:27:02 -08:00
Nathan Gauër
45b567be8d
[SPIR-V] Add partial order tests, assert reducible (#117887)
Add testing for the visitor and added a note explaining irreducible CFG
are not supported.
Related to #116692

---------

Signed-off-by: Nathan Gauër <brioche@google.com>
2024-11-28 16:33:01 +01:00
Nathan Gauër
53326ee0cf
[SPIR-V] Fix block sorting with irreducible CFG (#116996)
Block sorting was assuming reducible CFG. Meaning we always had a best
node to continue with. Irreducible CFG makes breaks this assumption, so
the algorithm looped indefinitely because no node was a valid candidate.

Fixes #116692

---------

Signed-off-by: Nathan Gauër <brioche@google.com>
2024-11-28 13:42:57 +01:00
Nathan Gauër
cba70550cc
[SPIR-V] Fix BB ordering & register lifetime (#111026)
The "topological" sorting was behaving incorrectly in some cases: 
the exit of a loop could have a lower rank than a node in the loop.
This causes issues when structurizing some patterns, and also codegen
issues as we could generate BBs in the incorrect order in regard to the
SPIR-V spec.

Fixing this ordering alone broke other parts of the structurizer, which
by luck worked. Had to fix those.

Added more test cases, especially to test basic patterns.

I also needed to tweak/disable some tests for 2 reasons:
 - SPIR-V now required reg2mem/mem2reg to run. Meaning dead stores
   are optimized away. Some tests require tweaks to avoid having the
   whole function removed.
 - Mem2Reg will generate variable & load/stores. This generates
   G_BITCAST in several cases. And there is currently something wrong
   we do with G_BITCAST which causes MIR verifier to complain.
   Until this is resolved, I disabled -verify-machineinstrs flag on
   those tests.

---------

Signed-off-by: Nathan Gauër <brioche@google.com>
2024-10-30 14:57:32 +01:00
Nathan Gauër
1ed65febd9
[SPIR-V] Add SPIR-V structurizer (#107408)
This commit adds an initial SPIR-V structurizer.
It leverages the previously merged passes, and the convergence region
analysis to determine the correct merge and continue blocks for SPIR-V.

The first part does a branch cleanup (simplifying switches, and
legalizing them), then merge instructions are added to cycles,
convergent and later divergent blocks.
Then comes the important part: splitting critical edges, and making sure
the divergent construct boundaries don't cross.

- we split blocks with multiple headers into 2 blocks.
- we split blocks that are a merge blocks for 2 or more constructs:
SPIR-V spec disallow a merge block to be shared by 2
loop/switch/condition construct.
- we split merge & continue blocks: SPIR-V spec disallow a basic block
to be both a continue block, and a merge block.
- we remove superfluous headers: when a header doesn't bring more info
than the parent on the divergence state, it must be removed.

This PR leverages the merged SPIR-V simulator for testing, as long as
spirv-val. For now, most DXC structurization tests are passing. The
unsupported ones are either caused by unsupported features like switches
on boolean types, or switches in region exits, because the MergeExit
pass doesn't support those yet (there is a FIXME).

This PR is quite large, and the addition not trivial, so I tried to keep
it simple. E.G: as soon as the CFG changes, I recompute the dominator
trees and other structures instead of updating them.

---------

Signed-off-by: Nathan Gauër <brioche@google.com>
2024-09-20 11:36:43 +02:00
Nathan Gauër
0c07e7c211
[SPIR-V] Sort basic blocks to match the SPIR-V spec (#102929)
The SPIR-V spec required basic blocks to respect some kind of ordering
(A block dominating another cannot be after in the binary layout).

---------

Signed-off-by: Nathan Gauër <brioche@google.com>
2024-08-21 13:08:25 +02:00
Nathan Gauër
a141a28c0c
[SPIR-V] Fix flakiness during switch generation. (#95001)
The case-list of the switches generated by this pass were not
"deterministic" (based on allocation patterns).
This is because the CaseList order relied on an unordered_set order.
Using the sorted exit target list for those should solve the problem.

Fixes #94961

Signed-off-by: Nathan Gauër <brioche@google.com>
2024-06-11 13:57:31 +02:00
Nathan Gauër
a5641f106a
[SPIR-V] Add pass to merge convergence region exit targets (#92531)
The structurizer required regions to be SESE: single entry, single exit.
This new pass transforms multiple-exit regions into single-exit regions.

```
      +---+
      | A |
      +---+
      /   \
   +---+ +---+
   | B | | C |  A, B & C belongs to the same convergence region.
   +---+ +---+
     |     |
   +---+ +---+
   | D | | E |  C & D belongs to the parent convergence region.
   +---+ +---+  This means B & C are the exit blocks of the region.
      \   /     And D & E the targets of those exits.
       \ /
        |
      +---+
      | F |
      +---+
```

This pass would assign one value per exit target:
B = 0
C = 1

Then, create one variable per exit block (B, C), and assign it to the
correct value: in B, the variable will have the value 0, and in C, the
value 1.

Then, we'd create a new block H, with a PHI node to gather those 2
variables, and a switch, to route to the correct target.

Finally, the branches in B and C are updated to exit to this new block.

```
      +---+
      | A |
      +---+
      /   \
   +---+ +---+
   | B | | C |
   +---+ +---+
      \   /
      +---+
      | H |
      +---+
      /   \
   +---+ +---+
   | D | | E |
   +---+ +---+
      \   /
       \ /
        |
      +---+
      | F |
      +---+
```

Note: the variable is set depending on the condition used to branch. If
B's terminator was conditional, the variable would be set using a
SELECT.
All internal edges of a region are left intact, only exiting edges are
updated.

---------

Signed-off-by: Nathan Gauër <brioche@google.com>
2024-06-03 11:35:55 +02:00