<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 14:48, Joe Groff via swift-dev <<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Dec 17, 2015, at 2:34 PM, Erik Eckstein via swift-dev <<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">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=""> %2 = load %1</font></div><div class=""><font face="Menlo" class=""> apply inout_violating_function // replaces *%1 and releases the original *%1.</font></div><div class=""><font face="Menlo" class=""> %3 = load %1</font></div><div class=""><font face="Menlo" class=""> %4 = ref_element_addr %3</font></div><div class=""><font face="Menlo" class=""> %ptr = load %4</font></div><div class=""><span class="" style="font-family: Menlo;">}</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=""> %2 = load %1</font></div><div class=""><font face="Menlo" class=""> apply inout_violating_function // replaces *%1 and releases the original *%1.</font></div><div class=""><span class="" style="font-family: Menlo;"> %4 = ref_element_addr %2</span></div><div class=""><font face="Menlo" class=""> %ptr = load %4 // load pointer from freed memory</font></div><div class=""><span class="" style="font-family: Menlo;">}</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 class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">inline</span><span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">bool</span><span class="Apple-converted-space"> </span>isNotAliasedIndirectParameter(<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">ParameterConvention</span><span class="Apple-converted-space"> </span>conv,</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">bool</span><span class="Apple-converted-space"> </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 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 style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">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></div></blockquote></div><br class=""><div class="">Do we really preserve memory safety today? It seems like <i class="">any</i> optimizations we might do could lead to half an object getting written, which can result in memory unsafety if <i class="">that</i> object is implemented using UnsafePointer (like *cough* Array).</div><div class=""><br class=""></div><div class="">Jordan</div></body></html>