OP3_TERNARY does not evaluate anything. MOVC does not require a bool, a comparison is added for floats, but everything else like bool/uint/int is passed directly as 'movc' argument. CMP is using >= 0.0 condition.
Sorry, let me try rephrasing. In the parser this patch series translates ?: to OP3_TERNARY, and it takes its initial argument verbatim, without trying to cast it to bool / compare it to zero first. Then, later, you lower that to OP3_MOVC, apparently to flush the condition argument to bool (although it doesn't handle int/uint for some reason). My question is, why do we need two different instructions? Why can't the sm4 backend just translate OP3_TERNARY directly?