<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jan 27, 2015 at 8:58 PM, 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="">> Ah, yes.  You are right, we cannot always assume that %y would be zero in<br>
> the second case.<br>
> This wouldn't be the first time we've lost information that we could use to<br>
> optimize a program by transforming it.<br>
><br>
> Do you think this result would be problematic?  It seems consistent with the<br>
> RFC and LLVM's current behavior.<br>
><br>
<br>
</span>The problem is not that we're losing information, the problem is that<br>
we're changing the behavior of a well-defined program.<br>
<br>
I'll try to put the whole argument in one place:<br>
<br>
We start with<br>
<br>
  %x = add nuw i32 %m, %n<br>
  %y = zext i32 %x to i64<br>
  %s = lshr i64 %y, 32<br>
  %addr = gep %some_global, %s<br>
  store i32 42, i32* %addr<br>
<br>
In the above program, for all values of %x, %s is 0.  This means the<br>
program is well-defined when %x is poison (since you don't need to<br>
look at %x to determine the value of %addr, in the same sense as you<br>
don't need to look at X to determine the value of "and X, 0"); and it<br>
stores 42 to &(%some_global)[0].  Specifically, the above program is<br>
well defined for "%m = %n = 2^32-1".<br>
<br>
Now if we do the usual transform of "zext (add nuw X Y)" => "add nuw<br>
(zext X) (zext Y)" then we get<br>
<br>
  %m.wide = zext i32 %m to i64<br>
  %n.wide = zext i32 %n to i64<br>
  %z = add nuw i64 %m.wide, %n.wide<br>
  %s = lshr i64 %y, 32<br>
  %addr = gep %some_global, %s<br>
  store i32 42, i32* %addr<br>
<br>
The new program does *not* have the same behavior as the old program<br>
for "%m = %n = 2^32-1".  We have changed the behavior of a<br>
well-defined program by doing the "zext (add nuw X Y)" => "add nuw<br>
(zext X) (zext Y)" transform.<br></blockquote><div><br></div><div>After some pondering and combing through LLVM's implementation, I think we must conclude that zexting a value with any poison bits creates poison in every new bit.</div><div><br></div><div>Considering the following program:</div><div><br></div><div>%zext = zext i32 %x to i64</div><div>%icmp = icmp i64 %zext, i64 1</div><div><br></div><div>we'd like to transform this to:</div><div><br></div><div>%icmp = icmp i32 %x, i32 1</div><div><br></div><div>Is it reasonable to say that '%icmp' in the before case is not poison but '%icmp' in the after case is poison?  LLVM assumes it can remove casts with impunity, I think this is a useful property to maintain.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class="HOEnZb"><font color="#888888"><br>
-- Sanjoy<br>
</font></span></blockquote></div><br></div></div>