<div dir="ltr"><div>Thanks for your answers.</div><div><br></div>Another example of unsound transformation on Boolean algebra. <div><br></div><div>According to the LLVM documentation (<a href="http://llvm.org/docs/LangRef.html#undefined-values">http://llvm.org/docs/LangRef.html#undefined-values</a>) it is unsafe to consider ' a & undef = undef ' and ' a | undef = undef ' but 'undef xor undef = undef' is safe. </div><div><br></div><div>Now, given an expression ((a & (~b)) | ((~a) & b)) where a and b are undef expressions, the value must be specialized to some constant (e.g. 0). </div><div><br></div><div>But, if the expression is transformed to $a xor b$ then it may return 'undef'. </div><div><br></div><div>As a result,  the transformation ' ((a & (~b)) |((~a) & b)) ~> xor a b '  is unsound. LLVM presently performs this transformation. <br></div><div><br></div><div><br></div><div>Best Regards,</div><div>soham</div><div><br></div><div>source</div><div>----------</div><div><br></div><div><div>int foo(){</div><div> int a,b; // unintialized and 'undef'</div><div> return ((a & (~b)) |((~a) & b));</div><div>}</div></div><div><br></div><div>unoptimized IR  // clang++ -emit-llvm udf.cpp -S</div><div>----------------------</div><div><br></div><div><div>define i32 @_Z3foov() #0 {</div><div>entry:</div><div>  %a = alloca i32, align 4                </div><div>  %b = alloca i32, align 4                </div><div>  %0 = load i32, i32* %a, align 4   </div><div>  %1 = load i32, i32* %b, align 4   </div><div>  %neg = xor i32 %1, -1              </div><div>  %and = and i32 %0, %neg</div><div>  %2 = load i32, i32* %a, align 4</div><div>  %neg1 = xor i32 %2, -1</div><div>  %3 = load i32, i32* %b, align 4</div><div>  %and2 = and i32 %neg1, %3</div><div>  %or = or i32 %and, %and2</div><div>  ret i32 %or</div><div>}</div></div><div><br></div><div>Here %or must return some constant e.g. 0.</div><div><br></div><div>optimized IR  // opt -O3 udf.ll -S</div><div>-------------------</div><div><br></div><div><div>define i32 @_Z3foov() #0 {</div><div>entry:</div><div>  ret i32 undef</div><div>}</div></div><div><br></div><div><br></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Sep 13, 2016 at 7:39 AM, Sanjoy Das <span dir="ltr"><<a href="mailto:sanjoy@playingwithpointers.com" target="_blank">sanjoy@playingwithpointers.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">Sanjoy Das wrote:<br>
> Here is a simpler example of a similar issue: `X - X` is not<br>
> equivalent `0`, in that `0` cannot be replaced with `X - X`, even<br>
> though `X - X` can be folded to `0`.<br>
<br></span>
I forgot to state that `X` above is some unknown value which can<br>
potentially be `undef`.  A full example would be:<br>
<br>
```<br>
define i32 @f_0(i32 %x) {<br>
  ret i32 0<br>
}<br>
<br>
define i32 @f_1(i32 %x) {<br>
  %v = sub i32 %x, %x<br>
  ret i32 %v<br>
}<br>
```<br>
<br>
`@f_1` can be optimized to `@f_0` but not vice versa, unless you<br>
somehow know that `%x` cannot be `undef`.<span class="HOEnZb"><font color="#888888"><br>
<br>
-- Sanjoy<br>
</font></span></blockquote></div><br></div>