[llvm-commits] [llvm] r92458 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/or.ll

Chris Lattner sabre at nondot.org
Mon Jan 4 21:14:33 PST 2010


On Jan 4, 2010, at 6:46 PM, Bill Wendling wrote:
>> -      V1 = 0; V2 = 0; V3 = 0;
>> +      
>> +      // ((V | N) & C1) | (V & C2) --> (V|N) & (C1|C2)
>> +      // iff (C1&C2) == 0 and (N&~C1) == 0
>> +      if ((C1->getValue() & C2->getValue()) == 0) {
>> +        if (match(A, m_Or(m_Value(V1), m_Value(V2))) &&
>> +            ((V1 == B && MaskedValueIsZero(V2, ~C1->getValue())) ||  // (V|N)
>> +             (V2 == B && MaskedValueIsZero(V1, ~C1->getValue()))))   // (N|V)
>> +          return BinaryOperator::CreateAnd(A,
>> +                               ConstantInt::get(A->getContext(),
>> +                                                C1->getValue()|C2->getValue()));
>> +        // Or commutes, try both ways.
>> +        if (match(B, m_Or(m_Value(V1), m_Value(V2))) &&
>> +            ((V1 == A && MaskedValueIsZero(V2, ~C2->getValue())) ||  // (V|N)
>> +             (V2 == A && MaskedValueIsZero(V1, ~C2->getValue()))))   // (N|V)
>> +          return BinaryOperator::CreateAnd(B,
>> +                               ConstantInt::get(B->getContext(),
>> +                                                C1->getValue()|C2->getValue()));
>> +      }
>>    }
>> 
> Hi Chris,
> 
> I'm having trouble verifying the logic here. I'm probably doing something wrong. First a comment, if C1 and C2 are both zero, then this is zero.

In the unlikely case that instcombine hadn't simplified that away, we'd still get valid code:

((V | N) & C1) | (V & C2) --> (V|N) & (C1|C2)

((V | N) & 0) | (V & 0) --> (V|N) & (0|0)  -> 0

> It can also be simplified if either one is zero. I don't know if those situations are caught before it gets to this point.

Yes, they are not worth special casing here.  X&0 -> 0 is already done elsewhere.

> Could you provide more insight into the result you got?

if C1&C2 = 0, then they have no common bits.  That means that the LHS and RHS of the outer 'or' are contributing disjoint sets of bits.  Since N&~C1 = 0, C1 has a superset of the bits possibly set in N.

This allows us to turn:
((V | N) & C1) | (V & C2) --> ((V | N | V) & (C1|C2))

V|N|V -> V|N.

However, beyond the math of the xform, I'd appreciate it if someone verified that the code actually matches the attempted xform :-)

-Chris



More information about the llvm-commits mailing list