[Mlir-commits] [mlir] [mlir] [arith] Fold trunc(extremum(ext(lhs), ext(rhs))) (PR #214658)

Mehdi Amini llvmlistbot at llvm.org
Fri Aug 7 02:58:56 PDT 2026


joker-eph wrote:

> It's not just code-gen, it's also intermediate pattern matchers that will need to keep converting back and forth for particular targets and not others throughout the pipeline.

It don't quite follow here, there is some assumptions that don't match how I design pass-pipeline design usually. That is while you're working on a "middle-end" (for any given abstraction level of course), you should stay in the "canonical form" for this abstraction level: there is no "back and forth". Only when you want to make it HW specific and lower further you would deconstruct it. 

> You could argue that reverting back to the plain version is a canonicalization, but then you lose the ability to propagate the trunc after other element-wise operations that may come after

Why would that be desirable? Wouldn't you want the element-wise operations to operate in bf16 form?
Also, strictly speaking, as long as you don't destroy information during canonicalization / keep it easily recoverable, you don't lose any ability: you just push onto the "trunc propagation logic" the need to handle operations with possible implicit trunc (that said such pass may be better structured as "denormalize by making the HW-specific truncation explicit in the IR and then do the propagation", again possibly as part of some pre-lowering pipeline).

In any case, to me you need to pick a canonical form between `matmul(bf16, bf16) -> bf16` and ` trunc(matmul(bf16, bf16) -> f32) -> bf16` , assuming both operation exist in the op-set of course (if the variant emitting `bf16` didn't exist there wouldn't be any question).


> Destroying intermediate type information is not helpful, even though it can be argued it's a canonicalization. 

One nit: canonicalization should never **destroy** information, the information isn't lost in the program semantics (of course any semantic-preserving transformation can lose non-semantic information, but that is the case of virtually every single canonicalization pattern).

> If the upstream discussions on canonicalization has thought us anything is that there's clear disagreement across the community on what a canonicalization is or when they're helpful.

My opinion on this topic after arguing for years is that there are people who probably should just never use the canonicalize pass before they operate with incorrect assumption about it and won't be able to design the rest of the pass pipeline appropriately around it. Fundamentally it's not about "this canonicalization help my mental model for my HW", it is the other way around: "the mental model and further optimizations need to be built around the canonical form": it the only way to compose and scale.

There is no point in arguing beyond the triptych of canonicalization principles ("don't lose information", "reasonably cheap patterns", "converge to make equivalent things look alike"), because if we let people argue the specific and decide base on taste, we'll inevitably go in the direction that *at the limit* is represented by "there is no acceptable canonicalization satisfying all constraints and thus we should do nothing".

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


More information about the Mlir-commits mailing list