[Bug tree-optimization/83541] Missed optimization with int overflow

glisse at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Jan 2 20:02:00 GMT 2018


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83541

--- Comment #4 from Marc Glisse <glisse at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #3)
> I've deliberately avoided doing this ... (turning SSA propagator UNDEFINED
> into a random value rather than keeping it effectively VARYING during
> propagation/simplification stage).  CCP is the only pass that even tries
> to handle arithmetic with UNDEF somehow.
> 
> The case in question could be teached to both EVRP and DOM (you need those
> conditional equivalences).

I am not sure if we can handle uninitialized variables and impossible values
(result of an overflow) together, they don't have the same properties. (I am
not saying that is what you suggested, just that I am too confused about UNDEF)

> Note that our constant folding machinery simply computes stuff in twos
> complement as it lacks a way to say "undefined".

The constant stuff has TREE_OVERFLOW. We usually drop_tree_overflow, but for
instance gimple_resimplify* could insert __builtin_unreachable() in seq (or
something similar if having __builtin_unreachable in the middle of a bb causes
trouble). Of course, important passes would then ignore this folding because
they don't want any extra insn :-( Maybe a way to say impossible would be nice,
I don't know if reusing error_mark_node would make sense.

> How useful would this be in practice?  Apart from breaking some invalid code
> in unexpected ways?

I don't believe the breaking would be particularly bad. We already exploit the
same information in VRP, it just shows up in different forms, sometimes by
letting you fold a condition, other times by creating an empty range, and it is
quite inconsistent to exploit it in one case and not the other. Replacing an
empty range with an arbitrary singleton as we do likely already breaks some
invalid code, and replacing an empty range with varying has the weird effect
that a tighter range gives less optimizations than a wider range.

__builtin_unreachable() often back-propagates a bit through trivial statements
and removes a branch, or reduces a PHI. The threader cannot handle everything.
Of course, it is hard to guess the true impact... I hit the VR_EMPTY case
regularly, but there is a strong bias in the code I look at ;-)


More information about the Gcc-bugs mailing list