The call to this tvm_if_then_else is declared here in the TVM IR and in the AST it is visible as intrinsic::tvm_if_then_else.
The question, why TVM had to define a different call to if_then_else instead of using the call toif_then_else provided by HalideIR? The HalideIR if_then_else, I guess should be visible as Call::if_then_else.
Another thing that related to this is that Simplify() uses the HalideIR simplifier and tvm_if_then_else cannot be simplified with that.
Currently, HalideIR simplification does not have rules for Call::if_then_else. However, if TVM DSL was generating Call::if_then_else, then we could add simplification rules for Call::if_then_else.
So, We are trying to understand the difference between these two types of if_then_else and why the TVM if_then_else is better and in what terms.
tvm’s if_then_else has the semantics that only one condition is evaluated so it can be used to safe-guard OOB access. We are in the process of upgrading simplification infrastructure https://github.com/dmlc/tvm/issues/2588 and the new infra should be able to simplify if_then_else
To answer your particular question, when we start to build the set of intrinsic we tried to only use the primitives ones in HalideIR where we clearly know the semantics(like shifts and bit casting) and create new tvm intrinsics for most other cases. To make sure the semantics of these intrinsics are clear.
if_then_else is a particular case where things can go either way and because we are not 100% if if_then_else was designed to handle OOB access, we decided to roll out the version in tvm where we know it won’t be handled differently in HalideIR.
As we are moving towards the new infra, we will hopefully unify more of the IRs and clarify those we are not sure about and hopefully make TVM’s IR infra more consistently internally.