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

--- Comment #9 from Marc Glisse <glisse at gcc dot gnu.org> ---
(In reply to Jeffrey A. Law from comment #8)
> I've spent a goodly part of the morning pondering this BZ.  While I think
> the semantics of b_c_p are under/ill defined and they will continue to cause
> problems, the as-if rule requires us to not optimize this case until such
> time as the semantics are changed.

Note that we can similarly get "spurious" fortify warnings from glibc headers.
On the other hand, those seem comparable to me to maybe_uninitialized warnings,
you have to accept some false positives from code that is dead but not in a way
the compiler can notice.

> If look at the observable effects, "b" is not a constant in the source and
> b_c_p will always evaluate to zero and we can never call ilog_NaN.  After
> path isolation, if "a" is zero then we call ilog_NaN.  This violates the
> as-if rule.

Uh, that's a very strict interpretation. In particular, a function parameter
can never satisfy it, whereas many users of bcp rely on inlining turning
parameters into constants.

> So the existence of a b_c_p call (and likely a b_o_s call) in a path means
> that path must not be isolated.  More generally a block with a b_c_p call
> must not be duplicated.  That is sufficient to fix this problem.  There's a
> secondary concern that removing edges which potentially lead to a b_c_p call
> can cause similar problems, but I'm inclined to punt that for now.

No duplication, so functions cannot be inlined or cloned until all the bcp
calls they contain have been folded. That's going to cause regressions. And it
actually breaks the fortify functions. I would also assume that bos is more
useful if you can isolate paths where you can give a better estimate for it.

> I'd love someone to step up and suggest semantics that would allow this kind
> of path isolation, but I think that's going to be difficult and the result
> would be highly non-obvious to folks trying to use b_c_p.

I think it is the reverse, actually. Looking at random uses of bcp in the
headers on my system, most uses are for optimization, with a safe fallback, and
are fine with any kind of optimization that duplicates them. The intuition is
that any time the compiler can prove it is handling a constant (be it through
inlining, threading, whatever), it may use the special code. This is fairly
easy for users to grasp. Checking uses (as in the linux testcase, or fortify
glibc headers) are the odd ones out, which require a bcp with unclear
semantics.

Reply via email to