<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/70780>70780</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[GlobalISel] Allow matching & rewriting MIFlags
</td>
</tr>
<tr>
<th>Labels</th>
<td>
llvm:globalisel
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
Pierre-vh
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
Pierre-vh
</td>
</tr>
</table>
<pre>
I am opening this ticket to gather feedback on how MIFlags matching/rewriting should be added to the MIR patterns used by the GISel combiners.
The feature itself is relatively simple to implement - I already got a WIP (https://reviews.llvm.org/D159111), but I am uncertain of the scope it should have, and of the syntax it should use.
## Current Behavior
Currently, MIFlags handling in Combiners is non-existent, and we've inherited two things from the ISel machinery that make MIFlags handling non-obvious:
- Some flags are propagated to output instructions from the root instruction (see `propagateFlags` in `GIMatchTableExecutorImpl.h`
- We sometimes mutate opcodes instead of rebuilding output instructions. I assume we preserve flag in those cases, but we can't choose which instruction gets mutated so this is really not obvious.
My proposition would be to:
- Disable flag propagation completely for combiners. It's not really necessary, and I once even tried to make it work properly (so propagate even for instruction built using C++ code) and it actually made things worse/more confusing. I think combiners need to control flags better.
- Make `GIM_MutateOpcode` always clear MIFlags for combiners, to avoid accidental flag propagation.
## Scope
##### What capabilities do we need?
I assume that at the bare minimum, we need to be able to match a given flag (and the absence of a flag), and write out some flags.
Do we also need a way to copy the flags from a source instruction? e.g. if we don't match all flags, but we want to preserve them.
## Syntax
The syntax is a bit messy. MIR patterns are piggybacking on top of DAG patterns which is really not ideal (and I am actually starting to wonder if we wouldn't be better off just parsing chunks of MIR? But that's a discussion for another time).
In my WIP, the syntax looked like:
```
def TestNewInst : GICombineRule<
(defs root:$dst),
(match (G_ZEXT $dst, $src, MIFlags<[FmAfn, FmReassoc]>)),
(apply (G_FADD $dst, $src, $src, MIFlags<[FmNoNans, FmAfn]>))>;
```
An alternative syntax i came up with is to use a dedicated DAG operator:
```
def TestNewInst : GICombineRule<
(defs root:$dst),
(match (G_ZEXT $dst, $src, (MIFlag FmReassoc, FmAfn)),
(apply (G_FADD $dst, $src, $src, (MIFlag FmNoNans,, FmAfn))>;
```
The latter is more flexible, because we can somewhat neatly express a "not" operation
```
def TestNewInst : GICombineRule<
(defs root:$dst),
(match (G_ZEXT $dst, $src, (MIFlag FmReassoc, (not FmAfn))), ; "not" is a DAG SDNode, but I guess it doesn't hurt to use it for this as well?
(apply (G_FADD $dst, $src, $src, (MIFlag FmNoNans,, FmAfn))>;
```
My preference is on the DAG form. Thoughts?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMV01v2zwS_jX0ZRDDlhx_HHxI4jrwId0XbYAu9lKMxJHFNxRpkCMr_veLoSzHbrPYwx62QODYEjkfzzzzDIkxmr0jWqv7R5VlfxkKge6Otcoydb8ZYcu1D-vL41Hh9Wm9A2zAH8gZtweuTQQ25RsxsIc9ck0BKiJdYPkG3kHtO3jZbS3uIzTIZW3cXmXbQF0wLCZi7VuroSBArUmLGa4JXnbf4IDMFFyENpKG4pRePO--k4XSN4VxFOJYTTZq8tB_vtYEFSG3gcBwJFuBiRDIIpsj2RNE0xwsiY_0pSHHcAc7QBsI9Qn2ngHhx-4vUNmyZj5ElT-obJsiPhrq4tjaYzP2QZLYTO9X0-lUZSuVPUHRMiRwWldSYDQOfJVCjqU_SEBDrjUeSXag05clJ8f4frWmjXSTmspyleXw1IYgQT9SjUfjw_WS8zt7EtsD5jU6bQVn4-BpAE1Qcd7d0buJTI6HYDpS2eJIYFxNwbBUo5NyGLePUAXfpFhTARqUUlKQoiBDg2_0u0_x4Yuj8W3C8SrWO_juG4IqrcdAcAj-gHvkngG-5UPLYFzk0JZsvLvyH7y_eSW1ikSg5pOLlRSImk8kbTWfPO9ehHuvWFj68k5lyz7smoMd12o-GSL6QRB9Q2waitC0jEzgD6XXFJM7wlSuQEVrrJb8PglzLByIsW0IOsmKIoVjn6jEwrWPBCVGigNnOvntVLZgKGsvr7valPVNhnviISQN0fd9l6iN1p7AeYYzzjekeTklXH00yUo3dBr738qxMVHA6QMdYJRNpZdOYemeyoerxoMdq2wRk_MhDiopRgyngVA78K4koCM54GD64iauGIbOh7fkioI9pSL6Dxr0e8TjNQ6CPEMbBfwnlT2q7BGkQCpbJX-GAUtuUzANahq42_kQSWXbxgeC0rsqmZBayYK3j6zAUR9k6R0Hb88MLUiUaDyA9SIZ9LT6-ZKq8o_EEyEc2g5PEUpLGC4dcYOcgMMe8OiNBixLo8kx2t-g_6z_v4uU_P788gc_pBtLPGBhrGFDEbQXikleKt9eb70QNXUwcmquQpqxMc40bSOBnrdKwCLRRa-eSckBYW9SlSRwlS2lAmIDi0hSdl8BppdnhUwSI7oijZN6rYd3DH1AmxQp2uh7nwgdnvpiHHrx76uRlAAh-jaUdM0PlW-BxvsxmEosad-31Tlae67mVeN16NLguvQp19R8invS519nzaDaERAKw9BQjKfx7exK4mb2-5NMxCQaDtgfBJzNw_PHunPT3_S00YR2QDbNlgu7I2NI85M9dN5pCuekU5P3eRd0Ji74qoK_28hwwJCap6xb9xYliJfdN4HtseXEg9TSCNrEso1Rek64i86nyS7aqLLVDUI7B81JZmbi9Qcq1vs30mDNG32ozXxy_ks_NVXwSpG_UrdzkUHlD_C8O4-pb60llT_1K0FQ0FTFpP5pKM905J5YV0v6Uqts-fzzX1_--QrDsif5FkN5NRrF9v3jtnmonDzdNt8IY_Slut-o_Euy_ItxPBx6oXr-uX3YbD41_h_dfPVf0cXek7i89pJ_Ufnjpwj1nw8O0ApN0jnmQjsosSFoD9AZTtRhL-cGKR9pU6ZhIRwThUX24c8qg8qWPURX0F_Q-Z_Rv7Z-gf5X-_8Nd-lxmxpU0E3Do7L0bgqbzm8FlSh49xM8CVonUuoI2Z6A3kVWpJtUljnPKsvOpRCp-uMLobKlaNBNPZKMg8ofr1JK6ic0-775mkbxcBTet5K9YdCeYq9IdRt4YKnhJC3pKIMROrL2MqD-XwVPByaqKKT5ZWIS65pSepUPzRhea9_ua44q3470OterfIUjWk_nq-Vitryfzkb1ulpMFnmxnM31tFzki_lqOpmusqrUxXJe6pkemXU2yfLpJJ9OJ_n9dDbWOU31NMfpKr-fzRZazSbUoLGX28bIxNjSejFZLCcjiwXZeL61yQqVP-ytL9CaSPZ8ewtreXNXtPuoZhNrIn_cXUZs2KZr33PaJid6db-BB2t9d7mmgcrm8HFRO-vZqA12fXs12huu22Jc-kZl2xRP_-_uEPzfVLLKtin8qLJtyuDfAQAA___8DJ-A">