<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Sanjoy,<div class="">            Here is another example directly out of your paper that</div><div class="">is not addressed by the paper, and also shows that copy-propagation</div><div class="">of “undef” is the root cause of the problem.  This problem disappears </div><div class="">if “k = undef” is not allowed to be copy-propagated to the two uses  </div><div class=""> “if (undef != 0)”   and   “t = 1 / undef” .</div><div class=""><br class=""></div><div class="">Peter Lawrence.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">3.2 Hoisting operations past control-flow</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">Consider this example:</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">if (k != 0) {</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">  while (c) {</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">use(1 / k); }</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">Since 1/k is loop invariant, LLVM would like to hoist it out of the loop. Hoisting the division seems safe because the top-level if-statement ensures that division by zero will not happen. This gives:</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">if (k != 0) {</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">  int t = 1 / k;</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">  while (c) {</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">use(t); }</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">Now consider the case where k is undef. Since each use of undef can yield a different result, we can have the top-level if-condition being true and still divide by zero, when this could not have happened in the original program if the execution never reached the division (e.g., if c was false). Thus, this transformation is unsound. LLVM used to do it, but stopped after it was shown to lead to end-to-end miscompilation.(3)</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 15px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 15px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">(3.  <a href="https://bugs.llvm.org/show_bug.cgi?id=21412" class="">https://bugs.llvm.org/show_bug.cgi?id=21412</a> )</span></div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div></body></html>