Sanjoy, Here is another example directly out of your paper that is not addressed by the paper, and also shows that copy-propagation of “undef” is the root cause of the problem. This problem disappears if “k = undef” is not allowed to be copy-propagated to the two uses “if (undef != 0)” and “t = 1 / undef” . Peter Lawrence. 3.2 Hoisting operations past control-flow Consider this example: if (k != 0) { while (c) { use(1 / k); } } 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: if (k != 0) { int t = 1 / k; while (c) { use(t); } } 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) (3. https://bugs.llvm.org/show_bug.cgi?id=21412 ) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170622/689ac55a/attachment.html>