[LLVMdev] Proposal to Remove Poison

Nuno Lopes nuno.lopes at ist.utl.pt
Tue Feb 17 09:29:09 PST 2015


> The following program is a little more interesting:
> define i1 @g() {
>   %mem = alloca i1
>   %load = load i1* %mem
>   %cmp0 = icmp eq i1 %load, 0
>   %cmp1 = icmp eq i1 %load, 1
>   %and = xor i1 %cmp0, %cmp1
>   ret i1 %and
> }
> 
> The intent of this program is to compare a memory location against all possible values the location might have.
> 
> If we ran LLVM's InstCombine pass then %and would have been replaced with the "expected" result of true.
> 
> If we instead ran SROA over @g, we would be left with:
>   %cmp0 = icmp eq i1 undef, false
>   %cmp1 = icmp eq i1 undef, true
>   %and = xor i1 %cmp0, %cmp1

This transformation is invalid in the light of current LLVM's semantics. Although it's fine according to the C standard (it's undefined behavior), it's highly non-intuitive.  (now I recall why 'xor %a, %a' could be different than 0).
 Sanjoy proposed in another email to make undef an instruction. That would actually solve this problem. SROA could replace the load with an undef instruction, forcing %and to be true. Undef instructions could be determinized to 0 in codegen (if not removed beforehand).

The downsize of having just one type of undef is that then all undefs are the same in the following sense:
%mem = alloca
%load = load %mem
%cmp = icmp slt %load, INT_MIN

With current LLVM, %cmp will always be false. With your proposal, %cmp will be undef, and therefore potentially true, which is strange.


Nuno





More information about the llvm-dev mailing list