[RFC][Standard] Add PowOp to Std Dialect


As the title says, I’m proposing we add a pow x, y op that computes x^y. For floating point operations, it seems like a justified mathematical operator. For integer types, I could imagine some concerns and would like to address them if needed.


Responding to the questions I anticipate as possible:

  • powf shouldn’t be std; it’s a special mathematical op/function call - yes, but it is almost certain that we are going to split std into multiple dialects including a math dialect, and then pow is fully justified
  • powf shouldn’t be added until there is the math dialect - this would be unfair to block all new ops in the dialect, effectively forcing whomever most needs the next op to be responsible for cleaning technical debt
  • powi wouldn’t make sense for negative integer exponents - we can work out these details over time. Even supporting just unsigned seems like enough reason to have the op, as people would want to do optimizations on unsigned powers. Another reason is to keep a mathi dialect mostly synced with a mathf dialect.

Please let me know of any concerns. Thanks,

I don’t know if it is “fair” or not, but this is however an effective way to get things done! :slight_smile:

It might also just drive people more towards their own dialect and less sharing. So I don’t think it is a good approach.

I vote for adding it and have the discussion about the math dialect independently. We should kick that off sometime soon, though.

This is a very common approach in LLVM though: I can recount how many time I had to refactor things because I wanted to add my feature, and folks who wrote the existing core required me to refactor first.

We can’t force people to contribute, but we don’t need to lower our standards.

The way the patch defines powi seems inconsistent from LLVM’s functionality.

  • llvm.pow.* (and this patch’s std.powf): float^float
  • llvm.powi.*: float^int
  • this patch’s std.powi: int^int

Does int^int as an op provide much value over a chain of integer multiplications? For the float^int case it is useful to have a special op like llvm.powi because we can leave the order of multiplications unspecified.

Personally, I’m fine just adding this to std for now (once we can settle on the design of the ops, of course). Moving it later is entirely mechanical.

Ahh, I was not aware of llvm.powi being a float^int, and that is a good point in regards to just doing a chain of multiplications which is not that much more code.

I would revise my proposal then to:

  • a powf that is equivalent to llvm.pow
  • No powi for now. Simple cases can just be represented with a loop, and an op with the purpose of avoiding the order of multiplications, exceeds the scope of what std should be responsible for.

I most likely only have 4 more days of work before a 4 week vacation, so I would not be able to implement or participate in a larger math dialect discussion. Given that, if we consider std to be frozen at this point with no additional features being accepted without first splitting the op into an appropriate dialect, I’ll make it clear to others reading this later that I’m not actively creating this op. If powf is considered a minor enough change that is not contributing to difficulties in later refactors, I would continue with the revised powf specification above that has similar properties to other ops like mulf.

To be clear: I’m perfectly fine with this angle right now!

This direction LGTM. Also, I assume an LLVM lowering will come soon? (given the small nature of this addition, I think that adding the LLVM lowering in the same patch would be fine as well)

I will follow up with LLVM and possibly other lowerings shortly after, but I will handle them as separate submissions. Then, if I make some silly mistake in actual code, the new Op won’t be rolled back with the faulty code.