In SSA, the variable can only have one definition, so if we want to use a predicated instruction in SSA form, we have to convert its outs to inout operands, and use Constraints to make sure these two operands will be alloc to the same register. For example an predicated mov instruction in ARM may be:
let isCommutable = 1, isSelect = 1 in
def MOVCCr : ARMPseudoInst<(outs GPR:$Rd),
(ins GPR:$false, GPR:$Rm, cmovpred:$p),
4, IIC_iCMOVr,
[(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm,
cmovpred:$p))]>,
RegConstraint<"$false = $Rd">, Sched<[WriteALU]>;
and this instruction can not use as a normal mov instruction, because of the inout operand. So there is another definition for normal mov:
def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr,
"mov", "\t$Rd, $Rm", []>, UnaryDP, Sched<[WriteALU]>
It is ok when we have few predicated instructions, but if most of the instructions in a target can be predicated, we need to generate an extra definition for each instruction which convert all def operands to inout operands if we want to predicated this instruction in SSA form.