Currently, constants have a property "Constant::canTrap", which is whether they contain a division that might have undefined behavior. If an instruction has a canTrap constant expression as an operand, and that constant expression contains a division with undefined behavior, the instruction has undefined behavior. For PHI nodes, the behavior is only undefined along the corresponding edges. This isn't documented anywhere in LangRef, but we use it to avoid certain transforms in a few optimization passes. For example, isSafeToSpeculativelyExecute checks whether instructions have a canTrap operand.
In practice, canTrap is almost never true: the only way create such an expression is to do something strange with the address of a global, so the denominator of a division is a complex constant expression. This means we have a lot of complexity with very little test coverage. So it would be nice if we could simplify the rules here.
This patch proposes to give up on the whole "canTrap" thing, and redefine the meaning of division in constant expressions. With this patch, if a constant expression divides by zero, or contains an overflowing divide, the result is poison. This simplifies a bunch of code. It also fixes an infinite loop bug involving a canTrap constant, a PHI, and an unsplittable critical edge. The downside is a slight performance hit: if we do end up with a divide constant expression with a complex denominator, we generate extra code to avoid the trap.
There are a few ways to reduce the performance hit that I haven't tried to implement. On architectures where division never traps, we could avoid generating extra code. We could also try to avoid constant-folding divide instructions that would result in a complex constant expression.
I'm not really happy with this formulation.
It basically says that we somewhere define things to be UB and here we say that it is not UB if it is a constant.