[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Dan Gohman djg at cray.com
Wed Jun 27 13:50:29 PDT 2007

>>> I think that undef udiv intmax -> 0, no?  If not, plz update
>>> instcombine as well.
>> intmax udiv intmax -> 1.
>> It seems like folding undef/X to undef isn't safe either though, with
>> the way it sounds like undef is intended to work. This code:
>>   %x = udiv i32 undef, %intmax
>>   %y = udiv i32 %x, 2
>> will always set %y to 0. Maybe instcombine can fold the second
>> udiv by looking through its operands, but it can't safely fold the
>> first. The best it could do is try to fold away all of %x's uses so
>> that %x isn't needed anymore.
> Ug, excellent point.  At this point, I'm inclined to just give up  
> folding of udiv undefs.  What do you think?

udiv isn't the only one, the way this is going...

  %x = mul i32 undef, 2
  %y = srem i32 %x, 2

  %x = and i32 undef, 0xffff0000
  %y = and i32 %x,    0x0000ffff

and so on for a lot of others.

add, sub, and xor, might be different though; the example below is

>> Even simple things like undef+X don't seem to be safe to fold.
>>   %x = undef;
>>   if (%x >= 0)
>>     %z = %y / (%x + 1);         // don't divide by undef!
> Fortunately, this isn't a problem.  LLVM has no copy instruction, so  
> the code is really this:
>>   if (undef >= 0)
>>     %z = %y / (undef + 1);         // don't divide by undef!
> There is nothing that specifies the two undefs are the same value.   
> Also, in C, if you have an undefined variable, you aren't guaranteed  
> to get the same undef value each time you read the variable, so  
> transforming C into LLVM is ok :)

In C, an uninitialized variable has an "indeterminate value", which is
potentially a trap representation, which can't even be multiplied by
zero without incurring undefined behavior. I don't know where it
suggests that a variable with indeterminate value might be different
on each read though. 

LLVM does so have copy instructions. The syntax is a little odd though,
and the keyword is spelled 'bitcast' ;-).

   %x = bitcast i64 undef to i64;
   if (%x >= 0)
     %z = %y / (%x + 1);         // don't divide by undef!

Now what should instcombine do?


Dan Gohman, Cray Inc.

More information about the llvm-commits mailing list