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

Evan Cheng evan.cheng at apple.com
Mon Aug 18 17:51:31 PDT 2008


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?

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




More information about the llvm-commits mailing list