[llvm-commits] [llvm] r54876 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll

Nick Lewycky nicholas at mxc.ca
Mon Aug 18 19:16:16 PDT 2008


Evan Cheng wrote:
> Hi Nick,
> 
> This patch caused 256.bzip2 to regress by 20% on x86 / Mac OS X. I  
> took a quick look at it but can't really figure out what's wrong. Can  
> you investigate?

I can try. Feel free to back out the patch if you like.

Nick

> Thanks,
> 
> Evan
> 
> 
> On Aug 17, 2008, at 12:34 AM, Nick Lewycky wrote:
> 
>> Author: nicholas
>> Date: Sun Aug 17 02:34:14 2008
>> New Revision: 54876
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=54876&view=rev
>> Log:
>> Xor'ing both sides of icmp by sign-bit is equivalent to swapping  
>> signedness of
>> the predicate.
>>
>> Also, make this optz'n apply in more cases where it's safe to do so.
>>
>> Added:
>>    llvm/trunk/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll
>> Modified:
>>    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
>>
>> Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=54876&r1=54875&r2=54876&view=diff
>>
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> ======================================================================
>> --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp  
>> (original)
>> +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun  
>> Aug 17 02:34:14 2008
>> @@ -5241,6 +5241,20 @@
>>       return new ICmpInst(I.getPredicate(), A, B);
>>     }
>>
>> +    ConstantInt *CI2;
>> +    // (icmp u/s (xor A SignBit), C) -> (icmp s/u A, (xor C SignBit))
>> +    if (!I.isEquality() &&
>> +        match(Op0, m_Xor(m_Value(A), m_ConstantInt(CI2)))) {
>> +      if (CI2->getValue().isSignBit()) {
>> +        const APInt &SignBit = CI2->getValue();
>> +        ICmpInst::Predicate Pred = I.isSignedPredicate()
>> +                                       ? I.getUnsignedPredicate()
>> +                                       : I.getSignedPredicate();
>> +        return new ICmpInst(Pred, A,
>> +                            ConstantInt::get(CI->getValue() ^  
>> SignBit));
>> +      }
>> +    }
>> +
>>     // If we have a icmp le or icmp ge instruction, turn it into the  
>> appropriate
>>     // icmp lt or icmp gt instruction.  This allows us to rely on  
>> them being
>>     // folded in the code below.
>> @@ -5491,35 +5505,49 @@
>>   // See if it's the same type of instruction on the left and right.
>>   if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
>>     if (BinaryOperator *Op1I = dyn_cast<BinaryOperator>(Op1)) {
>> -      if (Op0I->getOpcode() == Op1I->getOpcode() && Op0I- 
>>> hasOneUse() &&
>> -          Op1I->hasOneUse() && Op0I->getOperand(1) == Op1I- 
>>> getOperand(1) &&
>> -          I.isEquality()) {
>> -	switch (Op0I->getOpcode()) {
>> +      if (Op0I->getOpcode() == Op1I->getOpcode() &&
>> +          Op0I->getOperand(1) == Op1I->getOperand(1)) {
>> +        switch (Op0I->getOpcode()) {
>>         default: break;
>>         case Instruction::Add:
>>         case Instruction::Sub:
>>         case Instruction::Xor:
>> -          // a+x icmp eq/ne b+x --> a icmp b
>> -          return new ICmpInst(I.getPredicate(), Op0I->getOperand(0),
>> -                              Op1I->getOperand(0));
>> +          if (I.isEquality()) {
>> +            // icmp eq/ne a+x, b+x --> icmp eq/ne a, b
>> +            return new ICmpInst(I.getPredicate(), Op0I- 
>>> getOperand(0),
>> +                                Op1I->getOperand(0));
>> +          } else {
>> +            // icmp u/s (a ^ signbit), (b ^ signbit) --> icmp s/u  
>> a, b
>> +            if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0I- 
>>> getOperand(1))) {
>> +              if (CI->getValue().isSignBit()) {
>> +                ICmpInst::Predicate Pred = I.isSignedPredicate()
>> +                                               ?  
>> I.getUnsignedPredicate()
>> +                                               :  
>> I.getSignedPredicate();
>> +                return new ICmpInst(Pred, Op0I->getOperand(0),
>> +                                    Op1I->getOperand(0));
>> +              }
>> +            }
>> +          }
>>           break;
>>         case Instruction::Mul:
>> -          if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0I- 
>>> getOperand(1))) {
>> -            // a * Cst icmp eq/ne b * Cst --> a & Mask icmp b & Mask
>> -            // Mask = -1 >> count-trailing-zeros(Cst).
>> -            if (!CI->isZero() && !CI->isOne()) {
>> -              const APInt &AP = CI->getValue();
>> -              ConstantInt *Mask = ConstantInt::get(
>> -                                       
>> APInt::getLowBitsSet(AP.getBitWidth(),
>> -                                                            
>> AP.getBitWidth() -
>> +          // a * Cst icmp eq/ne b * Cst --> a & Mask icmp b & Mask
>> +          // Mask = -1 >> count-trailing-zeros(Cst).
>> +          if (Op0I->hasOneUse() && Op1I->hasOneUse() &&  
>> I.isEquality()) {
>> +            if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0I- 
>>> getOperand(1))) {
>> +              if (!CI->isZero() && !CI->isOne()) {
>> +                const APInt &AP = CI->getValue();
>> +                ConstantInt *Mask =
>> +                     
>> ConstantInt::get(APInt::getLowBitsSet(AP.getBitWidth(),
>> +                                                           
>> AP.getBitWidth() -
>>                                                        
>> AP.countTrailingZeros()));
>> -              Instruction *And1 = BinaryOperator::CreateAnd(Op0I- 
>>> getOperand(0),
>> -                                                            Mask);
>> -              Instruction *And2 = BinaryOperator::CreateAnd(Op1I- 
>>> getOperand(0),
>> -                                                            Mask);
>> -              InsertNewInstBefore(And1, I);
>> -              InsertNewInstBefore(And2, I);
>> -              return new ICmpInst(I.getPredicate(), And1, And2);
>> +                Instruction *And1 =
>> +                    BinaryOperator::CreateAnd(Op0I->getOperand(0),  
>> Mask);
>> +                Instruction *And2 =
>> +                    BinaryOperator::CreateAnd(Op1I->getOperand(0),  
>> Mask);
>> +                InsertNewInstBefore(And1, I);
>> +                InsertNewInstBefore(And2, I);
>> +                return new ICmpInst(I.getPredicate(), And1, And2);
>> +              }
>>             }
>>           }
>>           break;
>>
>> Added: llvm/trunk/test/Transforms/InstCombine/2008-08-17- 
>> ICmpXorSignbit.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll?rev=54876&view=auto
>>
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> = 
>> ======================================================================
>> --- llvm/trunk/test/Transforms/InstCombine/2008-08-17- 
>> ICmpXorSignbit.ll (added)
>> +++ llvm/trunk/test/Transforms/InstCombine/2008-08-17- 
>> ICmpXorSignbit.ll Sun Aug 17 02:34:14 2008
>> @@ -0,0 +1,22 @@
>> +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep -v xor
>> +
>> +define i1 @test1(i8 %x, i8 %y) {
>> +  %X = xor i8 %x, 128
>> +  %Y = xor i8 %y, 128
>> +  %tmp = icmp slt i8 %X, %Y
>> +  ret i1 %tmp
>> +}
>> +
>> +define i1 @test2(i8 %x, i8 %y) {
>> +  %X = xor i8 %x, 128
>> +  %Y = xor i8 %y, 128
>> +  %tmp = icmp ult i8 %X, %Y
>> +  ret i1 %tmp
>> +}
>> +
>> +define i1 @test3(i8 %x) {
>> +  %X = xor i8 %x, 128
>> +  %tmp = icmp uge i8 %X, 15
>> +  ret i1 %tmp
>> +}
>> +
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 




More information about the llvm-commits mailing list