<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/58500>58500</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [llvm-exegesis] getNonRedundantWriteProcRes assumes non-existant topological sorting
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            tools:llvm-exegesis
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          RKSimon
      </td>
    </tr>
</table>

<pre>
    getNonRedundantWriteProcRes has this comment:
```
  // This assumes that the ProcResDescs are sorted in topological order, which
  // is guaranteed by the tablegen backend.
```
AFAICT there isn't any actual topological sorting of the resources in tablegen - its sorted alphanumerically but that's about it. That's enough for a few scheduler models, but not in general.

e.g.
```
static const llvm::MCProcResourceDesc HaswellModelProcResources[] = {
  {"InvalidUnit", 0, 0, 0, 0},
  {"HWDivider",       1, 0, -1, nullptr}, // #1
  {"HWFPDivider",     1, 0, -1, nullptr}, // #2
  {"HWPort0",         1, 0, -1, nullptr}, // #3
  {"HWPort1",         1, 0, -1, nullptr}, // #4
  {"HWPort2",         1, 0, -1, nullptr}, // #5
  {"HWPort3",         1, 0, -1, nullptr}, // #6
  {"HWPort4",         1, 0, -1, nullptr}, // #7
  {"HWPort5",         1, 0, -1, nullptr}, // #8
  {"HWPort6",         1, 0, -1, nullptr}, // #9
  {"HWPort7",         1, 0, -1, nullptr}, // #10
  {"HWPort01",        2, 0, -1, HaswellModelProcResourceSubUnits + 1}, // #11
  {"HWPort04",        2, 0, -1, HaswellModelProcResourceSubUnits + 3}, // #12
  {"HWPort05",        2, 0, -1, HaswellModelProcResourceSubUnits + 5}, // #13
  {"HWPort06",        2, 0, -1, HaswellModelProcResourceSubUnits + 7}, // #14
  {"HWPort15",        2, 0, -1, HaswellModelProcResourceSubUnits + 9}, // #15
  {"HWPort16",        2, 0, -1, HaswellModelProcResourceSubUnits + 11}, // #16
  {"HWPort23",        2, 0, -1, HaswellModelProcResourceSubUnits + 13}, // #17
  {"HWPort56",        2, 0, -1, HaswellModelProcResourceSubUnits + 15}, // #18
  {"HWPort015",       3, 0, -1, HaswellModelProcResourceSubUnits + 17}, // #19
  {"HWPort056",       3, 0, -1, HaswellModelProcResourceSubUnits + 20}, // #20
  {"HWPort237",       3, 0, -1, HaswellModelProcResourceSubUnits + 23}, // #21
  {"HWPort0156",      4, 0, -1, HaswellModelProcResourceSubUnits + 26}, // #22
  {"HWPortAny",       8, 0, 60, HaswellModelProcResourceSubUnits + 30}, // #23
};
```
vs
```
static const llvm::MCProcResourceDesc AlderlakePModelProcResources[] = {
  {"InvalidUnit", 0, 0, 0, 0},
  {"ADLPPort00",      1, 0, -1, nullptr}, // #1
  {"ADLPPort00_01",   2, 0, -1, AlderlakePModelProcResourceSubUnits + 1}, // #2
  {"ADLPPort00_01_05", 3, 0, -1, AlderlakePModelProcResourceSubUnits + 3}, // #3
  {"ADLPPort00_01_05_06", 4, 0, -1, AlderlakePModelProcResourceSubUnits + 6}, // #4
  {"ADLPPort00_01_05_06_10", 5, 0, 112, AlderlakePModelProcResourceSubUnits + 10}, // #5
  {"ADLPPort00_05",   2, 0, -1, AlderlakePModelProcResourceSubUnits + 15}, // #6
  {"ADLPPort00_05_06", 3, 0, -1, AlderlakePModelProcResourceSubUnits + 17}, // #7
  {"ADLPPort00_06",   2, 0, -1, AlderlakePModelProcResourceSubUnits + 20}, // #8
  {"ADLPPort01",      1, 0, -1, nullptr}, // #9
  {"ADLPPort01_05",   2, 0, -1, AlderlakePModelProcResourceSubUnits + 22}, // #10
  {"ADLPPort01_05_10", 3, 0, -1, AlderlakePModelProcResourceSubUnits + 24}, // #11
  {"ADLPPort02",      1, 0, -1, nullptr}, // #12
  {"ADLPPort02_03",   2, 0, -1, AlderlakePModelProcResourceSubUnits + 27}, // #13
  {"ADLPPort02_03_07", 3, 0, -1, AlderlakePModelProcResourceSubUnits + 29}, // #14
  {"ADLPPort02_03_07_08_11", 5, 0, 72, AlderlakePModelProcResourceSubUnits + 32}, // #15
  {"ADLPPort02_03_11", 3, 0, -1, AlderlakePModelProcResourceSubUnits + 37}, // #16
  {"ADLPPort03",      1, 0, -1, nullptr}, // #17
  {"ADLPPort04",      1, 0, -1, nullptr}, // #18
  {"ADLPPort04_09",   2, 0, 48, AlderlakePModelProcResourceSubUnits + 40}, // #19
  {"ADLPPort05",      1, 0, -1, nullptr}, // #20
  {"ADLPPort06",      1, 0, -1, nullptr}, // #21
  {"ADLPPort07",      1, 0, -1, nullptr}, // #22
  {"ADLPPort07_08",   2, 0, -1, AlderlakePModelProcResourceSubUnits + 42}, // #23
  {"ADLPPort08",      1, 0, -1, nullptr}, // #24
  {"ADLPPort09",      1, 0, -1, nullptr}, // #25
  {"ADLPPort10",      1, 0, -1, nullptr}, // #26
  {"ADLPPort11",      1, 0, -1, nullptr}, // #27
  {"ADLPPortInvalid", 1, 0, -1, nullptr}, // #28
};
```
Most intel models used to have a 'Any' resource group that would be sorted after the numeric resource units, but with Alderlake the groups are now split by scheduler and their reservation stations, and by using numbers in the group names the dodgy sorting exegesis was relying on breaks.

This is probably the source of the problem first identified in Issue #37045
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy9WVtv4jgU_jXwYhU5zpUHHuigaka7XVWdWc0jchITvGNsZDtl-fdrGwglcVomoK0okCb-vnP38Wkuyv2sIvovwV9JWfMSc_1TUk1epCheiQJrrIBeUwUKsdkQrkfhfAQXIzgfJfD4cpcAjNCTeYEf9mGsVL0hdiXW5o2AI9yCqMLclQQoITUpAeVAi61goqIFZkDIksgR-gJ2a1qsW8gGt6qxNBISszLfO2CNc0YqwkGOi1-ElxOvdPOn-bcvP-wCQ00VH6FUA8z3ABe6NrzvZbCSUV4BsXIEkihRy8IoY2U9sT0AqtVJCcy2a8yNwtICsD3Ia-1UNzRG21yYS6onxjTHPxEu6moNVkICDFZkB1SxNtZnRIKNKAlT1gQWhAttaQ0jkZiddHPvZFL5dVUaa1oYf3GlAWNvG-uycP785egDp411BPiK1Y4w9mwp399Uo_hxFC_AKDS_6WPjBvMVoW_8DTNa_s2p0QVZQWH7LV2Yz8tVX38u6Bt1znVrDj9Bs-jBfeU1Y1stDwAnt49QGLTBnl66cNeCoTbYi_EivJDrerDQBxYMBIt8YGggWOwDCweCJT6waCBY6gOLB4JlPrBkINjUB5YOBAugN9BawYFaaH05-b3Obcopg_xoROiQdVLEkUV3IAu7ZP4Uiu9AFnfJvCkGkzuQpV0ybwoG99Bs2iXzpmhwD80CT4R4cxiF92DzhIg_ye-imydGvFUAtvwWDmLzBIm3TMCWcoPYEOxuV94yYqvo7WxdvyF_HQkulYsGsSVdNm8hmfP9hW5Zw5bA66uWx5LHSmJvhI_e3ulN3dhSzZlpShj-RV7-j65qvvjzxfnnon0Z2FWdwZbvNql2in6g4CdbFPqAbtlsHu1AvpavG8rhx3zLZgtpR_O1lN14jj6lXAYnV8UNaxCg37JsN7Ljft74dk92623yAd_ZrkNd6Sm5aT9hcrOCnqKb9fAFQ_Js2gd2D--Y9Z81nheE5wAc6h4Ufdp9NoxoUF3qqxRoCcPbDebZ0PtKhSVcwvRWg3lav75KcWRcwmwZBJ1Kkf5WoQg9odFXKRxvwzi4CHts21crwkGh0VcIokFofWkeLeHUE2hR9jvGiLplpd05NoTxEPHbnWGDlgxC68vhdBBaXw7b0L45h6NuZKO-HM4Gid-Xn9NBaD1ZFwxq21BPRgWDNifUk1HHhvQIeTVa9mmL_SyUnWlqwo6zTlArUgItwBq_EYANTOpOAGkzegWVFPX2MEzeiZqVIG8GyHiliXSD2uMA9ryqtvFi5bOT1B3V63N8uQUO9TCN5mIH1JZRbcfK52Es5qV9kkoLSuSbOQUIDtxpwBwFLLR9wiyplZ0YGwlyIg-D4hM-4PgwCCegFGW1b8bL5F9SEUUV2GFl4NnezZw5yCXBv9TFqNeN1M1rK0WOc3YYfB-VPE6p7S1GNmBFpTVvSbimK3oYsH9TqiauI05hFI_JLEiSBKVhFIbjchaW03CKx5pqRmbmiGKPNw8n4ex55aP_Dpzm_Fxws4Yay3DtG6aPa8lma623yp6cXLhUxiF1PinExly4M9Xh48Go8g8pzDHoiVrBjZmf4iyGcLye5UFcxihbwVUcTDFGMJrCNIqSMIRhmGTlmOHcRJRVwwSuFoJZvkuNTEDHizGdIYhQABEMjB3icJIFWQDjVYGybBWkxXQUQbLBlE3s6omQ1VjOHFBeV8rcZEZZdb5pDEErTpwFLT6u9VrI2esf3-lG8LHTZObU-A_Yot6v">