<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=""><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Sanjoy,<div class="">            In that case I change my answer and say that the illegal</div><div class="">optimization was (step 1) hoisting the “nsw” out of the if-statement,</div><div class=""><br class=""></div><div class="">When inside the protection of the if-clause the “nsw” was conditional on</div><div class="">the if-clause, but when you hoisted it out of the if-statement there is no </div><div class="">reason to continue assuming “nsw” is true. (This is true regardless of how</div><div class="">the original “nsw” got there, either by language definition or by analysis).</div><div class=""><br class=""></div><div class="">“Nsw” isn’t an opcode, it is analysis information, and as we all know</div><div class="">Analysis information can and does get invalidated by transformations.</div><div class="">This is a case in point.</div><div class=""><br class=""></div><div class="">I think the “nsw” got hoisted out of the if-statement by accident, assuming</div><div class="">it was part of the opcode, but we have just seen that this is incorrect.</div><div class=""><br class=""></div><div class="">   - - - - - - - - - - - - - - - - - - - -</div><div class=""><br class=""></div><div class="">If the above analysis is correct (I am pretty sure it is, but have been known</div><div class="">to make mistakes!), then my concern is that since this example was</div><div class="">incorrectly root-caused I am not sure we are ready to commit to “poison”</div><div class="">and “freeze” changes, and need to see more original source causes of</div><div class="">end-to-end-miscompilation to be sure we haven’t also mis-diagnosed those</div><div class="">as well.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Peter Lawrence.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 5, 2017, at 12:02 PM, Sanjoy Das <<a href="mailto:sanjoy@playingwithpointers.com" class="">sanjoy@playingwithpointers.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Hi Peter,<br class=""><br class="">On Mon, Jun 5, 2017 at 9:43 AM, Peter Lawrence<br class=""><<a href="mailto:peterl95124@sbcglobal.net" class="">peterl95124@sbcglobal.net</a>> wrote:<br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">I think it is valid by definition -- since "A *nsw B" does not sign<br class="">wrap, "sext(A *nsw B)" == (sext A) * (sext B).  In other words, these<br class="">two expressions are inequal only if "A *nsw B" sign wraps.<br class=""></blockquote><br class="">The way you use “nsw” it seems like an assertion or an assumption.<br class=""></blockquote><br class="">Yes, that is correct.<br class=""><br class=""><blockquote type="cite" class="">Where did the “nsw” come from, is it from the source language definition,<br class="">Or compiler derived analysis information ?<br class=""></blockquote><br class="">Both are possible.  In C/C++, as you know, most (all?) signed<br class="">arithmetic can be marked nsw.  In many cases the optimizer will also<br class="">infer nsw if it can prove the arithmetic does not overflow (e.g. if (a<br class="">!= INT_SMAX) b = a + 1;  ==> if (a != INT_SMAX) b = a+nsw 1;).<br class=""><br class="">-- Sanjoy<br class=""></div></div></blockquote></div><br class=""></div><div class=""><br class=""></div><div class="">Here’s the original source example for context</div><div class="">———————————————————————————————</div><div class=""><div><h1 style="background-color: rgb(255, 255, 255);" class=""><span style="font-size: 12px;" class="">[llvm-dev] RFC: Killing undef and spreading poison</span></h1><h1 style="background-color: rgb(255, 255, 255);" class=""><span style="font-size: 12px;" class=""><b class="">Sanjoy Das via llvm-dev</b> <a href="mailto:llvm-dev%40lists.llvm.org?Subject=Re%3A%20%5Bllvm-dev%5D%20RFC%3A%20Killing%20undef%20and%20spreading%20poison&In-Reply-To=%3C5826CAF4.9000409%40playingwithpointers.com%3E" title="[llvm-dev] RFC: Killing undef and spreading poison" class="">llvm-dev at lists.llvm.org </a></span></h1><i style="background-color: rgb(255, 255, 255);" class="">Fri Nov 11 23:55:32 PST 2016</i></div><div><br class=""></div><div><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">Firstly consider this sequence of transforms:

   for (...) {
     if (condition){
       i32 prod = x *nsw y
       i64 prod.sext = sext prod to i64
       i64 t = K `udiv` (-1 + (sum.prod >> 32))
       use(t)
     }
   }

==> (step 1) multiplication and sext can be speculated

   i32 prod = x *nsw y
   i64 prod.sext = sext prod to i64
   for (...) {
     if (condition){
       i64 t = K `udiv` (-1 + (prod.sext >> 32))
       use(t)
     }
   }

==> (step 2) known bits analysis on sext to prove divisor is non-zero

   i32 prod = x *nsw y
   i64 prod.sext = sext prod to i64
   i64 t = K `udiv` (-1 + (prod.sext >> 32))
   for (...) {
     if (condition){
       use(t)
     }
   }

==> (step 3) commute sext through nsw multiplicationa

   ;; i32 prod = x *nsw y
   i64 prod.sext = (sext x) *nsw (sext y)
   i64 t = K `udiv` (-1 + (prod.sext >> 32))
   for (...) {
     if (condition){
       use(t)
     }
   }


Now we've managed to introduce a fault if we were in case 1 -- the
source program was well defined but the target program divides by
zero.</pre><div class=""><br class=""></div></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></body></html>