SCF dialect

Hello again,

While looking into the SCF dialect I noticed that its optimizations focus mainly on loops. A piece of code like the following will never get fused.

  %o1 = scf.if %c -> (i32) {
    %x = call @f(%a) : (i32) -> (i32)
    scf.yield %x:i32
  } else {
    %x = call @g(%a) : (i32) -> (i32)
    scf.yield %x:i32
  }
  
  %o2 = scf.if %c -> (i32) {
    %x = call @h(%o1) : (i32) -> (i32)
    scf.yield %x:i32
  } else {
    %x = call @i(%o1) : (i32) -> (i32)
    scf.yield %x:i32
  }

Is this because this transformation is done at LLVM level?
So, in a sense, scf.if is just syntactic sugar with no optimization exploiting it algorithmically (not even constant propagation touches it natively), as opposed to scf.loop which is used for tiling.

Best,
Dumitru

Like many other dialects, SCF is need-driven. We almost never try to be exhaustive in any sense. Nobody needed a transformation that you describe, so nobody implemented it. If you do, patches are always welcome :slight_smile:

2 Likes

Yes as Alex said. The fact that LLVM does it and is the most common backend folks have been using, does probably result in this not being prioritized much yet (e.g., see the recent cond_br canonicalization, it could have been done a long time ago but bubbled recently as folks hit it for a specific codegen). This does seem useful and the legality analysis might be expressible quite generally so that it could apply for multiple conditional control flow ops.

1 Like

I’m considering doing it (together with my PhD). But this would be our first patch, and I’m a bit stressed about it. Le me think.