Given an expression, we have to do computations in some other type than the type of the expression? Now that's just silly.
Sure, but that's not what I said. If the expression has some type X, then we should be doing our computations in type X. Right. Let me try again and take a simpler example. If we have subtype T is Integer range 20..50; Y: T; ... Y + 1 ... What the tree looks like is a PLUS_EXPR of type "Integer" (the base type of T), not T, whose first operand is a NOP_EXPR converting Y to Integer and whose second operand is the constant 1 also of type Integer, not T. So the expression is of type Integer and that's what we do the computation in. If the context of that expression is Y := Y + 1; then there'll be a conversion to type T (and possibly a bounds check) of the RHS of the MODIFY_EXPR. VRP will know that the results of the PLUS_EXPR are [21,51] (not [21,50]!). The bounds check will be against [20,50], so VRP could convert it to a test of "!= 51" if it wanted.