<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 17, 2015, at 2:34 PM, Erik Eckstein via swift-dev &lt;<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi,<div class=""><br class=""></div><div class="">I'm currently working on improving alias analysis in the optimizer and I run into following problem:</div><div class=""><br class=""></div><div class="">If alias analysis assumes that inout may not alias any other object, we may violate memory safety. Note that currently it's not always assumed, e.g. not in computeMemoryBehavior for apply insts.</div><div class=""><br class=""></div><div class="">As I understood, if the inout rule is violated, the program is not expected to behave as intended, but is still must be memory safe.</div><div class="">For this reason we had to insert explicit checks for inout violations in the stdlib, e.g. in ArrayBuffer: _precondition(_isNativeTypeChecked == wasNativeTypeChecked, "inout rules were violated: the array was overwritten")</div><div class=""><br class=""></div><div class="">Now with improved alias analysis and assuming inout-no-alias, the optimizer (specifically redundant load elimination) may eliminate these precondition checks in the stdlib.</div><div class="">And I can think of other cases, e.g.</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">sil @test(@inout %1 : $*C) {</font></div><div class=""><font face="Menlo" class="">&nbsp; %2 = load %1</font></div><div class=""><font face="Menlo" class="">&nbsp; apply inout_violating_function // replaces *%1 and releases the original *%1.</font></div><div class=""><font face="Menlo" class="">&nbsp; %3 = load %1</font></div><div class=""><font face="Menlo" class="">&nbsp; %4 = ref_element_addr %3</font></div><div class=""><font face="Menlo" class="">&nbsp; %ptr = load %4</font></div><div class=""><span style="font-family: Menlo;" class="">}</span></div><div class=""><br class=""></div><div class=""><div class="">Redundant load elimination may optimize this to</div></div><div class=""><br class=""></div><div class=""><div class=""><font face="Menlo" class="">sil @test(@inout %1 : $*C) {</font></div><div class=""><font face="Menlo" class="">&nbsp; %2 = load %1</font></div><div class=""><font face="Menlo" class="">&nbsp; apply inout_violating_function // replaces *%1 and releases the original *%1.</font></div><div class=""><span style="font-family: Menlo;" class="">&nbsp; %4 = ref_element_addr %2</span></div><div class=""><font face="Menlo" class="">&nbsp; %ptr = load %4 &nbsp;// load pointer from freed memory</font></div><div class=""><span style="font-family: Menlo;" class="">}</span></div><div class=""><br class=""></div></div><div class="">What I propose is to add a utility function in Types.h</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">inline</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">bool</span> isNotAliasedIndirectParameter(<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">ParameterConvention</span> conv,</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">bool</span> assumeInoutIsNotAliasing)</div></div><div class=""><br class=""></div><div class="">and optimizations, which use this function, must decide if it is safe to pass true in&nbsp;assumeInoutIsNotAliasing. This might be the case for high-level optimizations like COW array opts.</div><div class="">For alias analysis I think we have to go the conservative way.</div><div class=""><br class=""></div><div class="">John, Joe: any comments?</div></div></div></blockquote><br class=""></div><div>I agree that we can't make a blanket assumption that inout is noalias. Arnold made a similar conclusion last year, so I think we already treat them as aliasing. IRGen won't apply the LLVM noalias attribute to inout parameters, for instance. It's probably better to target `inout` with specific known-acceptable optimizations (load forwarding, writeback elimination, transforming to input-result pair, etc.) than generally treating it as noalias.</div><br class=""><div class="">-Joe</div></body></html>