[llvm] [IR] Add zext nneg flag (PR #67982)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 3 13:54:59 PDT 2023


nikic wrote:

> I think a better question is : should we add the `nneg` attribute to `zext` or `sext` ? or even : Is there an underlying instruction, such as `ext` that could represent what we want ? We could have `ext sign ...` `ext zero ...` and `ext nneg ...`. All of the tree scenarios (signed, zero and zero but we know its positive) seems to be mutually exclusive. But at the end, probably that `zext nneg` is the easiest to implement (compared to renaming `sext -> ext sign` and `zext -> ext zero`) and makes the most sens as we are zero-expanding

Yeah, I think this basically comes down the how to hard it is to implement. Adding a new flag to zext is based on the well-understood existing mechanism of poison-generating flags and degrades gracefully: All existing zext folds continue working. If a fold doesn't consider the nneg flag (as will be the case for all folds initially), the worst that can happen is that the flag is dropped or a fold that could make use of it doesn't, but we'll never end up doing something worse than we do now. This allows gradual introduction without breaking anything.

The main disadvantage to `zext nneg` I see is that zext continues to be "privileged" as our choice of canonicalization. Optimizations expecting a zext can just look for a zext. Optimizations expecting an sext may have to look for a "sext or zext nneg".

-----

For the "common ext instruction" approach, the way I would frame this is probably that there are `ext zero`, `ext sign` and `ext zero sign`, where the latter is both a zero and a sign extend, returning poison if those two options conflict. The "m_ZExt" would match any ext with zero flag (either `ext zero` or `ext zero sign`) and m_SExt would do the same with the sign flag. Two exts would be considered "identical if defined" if they have at least one common flag. Flag intersection would then be that common flag. This means that `ext zero sign` could be combined with both `ext zero` and `ext sign` by dropping the appropriate flag. The "drop poison-generating flags" operation would still have to make an arbitrary choice, such that `freeze(ext zero sign)` would presumably become `ext zero (freeze)`.

The nice thing about this approach is that zext is no longer privileged, the model forces handling zext and sext on the same footing. On the other hand, this would be a major IR change, and it doesn't quite fit into the usual paradigm of poison-generating flags (because these "flags" aren't the kind that can be simply dropped).

(A further extension of this would be to also have plain `ext` which is extension without forcing the high bits to be zero or sign. In other words, this represents the anyext operation. But I don't think we actually want something like this at the IR level, because this would have to be based on undef bits, which is a concept we'd rather get rid off.)

https://github.com/llvm/llvm-project/pull/67982


More information about the llvm-commits mailing list