<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8">
</head>
<body>
<div style="font-family:sans-serif"><div style="white-space:normal">
<p dir="auto">On 4 Dec 2018, at 13:16, Sanjoy Das wrote:</p>

<blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px">
<p dir="auto">On Mon, Dec 3, 2018 at 11:49 PM John McCall <a href="mailto:jmccall@apple.com" style="color:#777">jmccall@apple.com</a> wrote:</p>

<blockquote style="border-left:2px solid #777; color:#999; margin:0 0 5px; padding-left:5px; border-left-color:#999">
<p dir="auto">Piotr's proposal unfortunately doesn't give us a good name for the class<br>
of optimizations that require being listed in supported_optimizations.<br>
In earlier discussions I called them "brittle", but I can understand why<br>
nobody wants to call their optimization that, so let's call them<br>
"good-faith optimizations" instead since they rely on the good faith of<br>
all the participating code.</p>

<p dir="auto">Every optimization has to know how to maintain the structural rules of<br>
LLVM IR; that's what makes them structural rules. We don't want the set of<br>
structural rules to substantially change because such-and-such good-faith<br>
optimization is in effect because that would require arbitrary transforms<br>
to check the supported_optimizations list before they knew which rules to<br>
follow. Instead, the burden is on the optimization designer to pick IR<br>
constructs that won't be messed up by an arbitrary transform with no special<br>
knowledge of the optimization. The only thing the optimization designer<br>
can rely on is this:</p>

<p dir="auto">other transforms will preserve the apparent semantics of the function and<br>
other transforms will maintain the standard structural rules of LLVM IR.</p>
</blockquote>

<p dir="auto">Ok.  Just to make sure we're on the same page, if this was all there<br>
is we would not need this attribute right?  All LLVM optimizations do<br>
need to preserve semantics and structural properties anyway?</p>
</blockquote>

<p dir="auto">We need this attribute because interprocedural optimizations otherwise<br>
break good-faith optimizations, so yes, my suummary here is missing some<br>
qualification (that I included in the next paragraph, but with a slightly<br>
different spin).  So let me restate this.</p>

<p dir="auto">The designer of a good-faith optimization can rely on this:</p>

<ul>
<li>other transforms will preserve the apparent semantics of the function,</li>
<li>other transforms will maintain the standard structural rules of LLVM IR, and</li>
<li>interprocedural transforms will honor supported_optimizations as mentioned
in Piotr's proposal --- and, in particular, will intersect the
supported_optimizations list whenever moving code into a function.</li>
</ul>

<p dir="auto">Note that IPO is generally permitted to partially inline or outline code,<br>
and so good-faith optimizations that e.g. require two instructions to be moved<br>
in tandem or not at all must use tokens to establish that unbreakable<br>
relationship.</p>

<blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px">
<blockquote style="border-left:2px solid #777; color:#999; margin:0 0 5px; padding-left:5px; border-left-color:#999">
<p dir="auto">So the defining property of a good-faith optimization is that:<br>
- there are rules which participating functions are expected to follow on<br>
pain of undefined behavior but which LLVM IR doesn't require every function<br>
to follow, and<br>
- those rules will be preserved by any transform that doesn't move code<br>
between functions and which preserves the apparent function semantics<br>
and maintains the standard structural rules of LLVM IR.</p>
</blockquote>

<p dir="auto">In other words, certain things are UB in functions tagged with<br>
supported_optimizations that are not UB otherwise?  This breaks code<br>
hoisting transformations right?  I.e.<br>
isSafeToSpeculativelyExecute(Inst) will have to return false if Inst<br>
is in a function with a non-empty supported_optimizations?</p>
</blockquote>

<p dir="auto">Good question.  I would consider that to be an unacceptable intrusion:<br>
intraprocedural transforms should never have to be aware of<br>
supported_optimizations (unless they're implementing a good-faith<br>
optimization, of course) and interprocedural transforms should only have<br>
to be aware of supported_optimizations in the narrow sense outlined<br>
by Piotr.  If something about the optimization's representation in IR<br>
is unsafe to speculate, it should be made impossible to speculate for<br>
standard semantic/structural reasons, like having apparently arbitrary<br>
side-effects.</p>

<p dir="auto">I think the right way to formalize this is to say that, while the<br>
good-faith optimization may impose additional UB rules on the function,<br>
it must guarantee that transforms that are well-behaved as described<br>
above --- i.e. that preserve standard structure and semantics and which,<br>
if interprocedural, appropriately honor supported_optimizations --- will<br>
never introduce new UB.</p>

<p dir="auto">John.</p>
</div>
</div>
</body>
</html>