[llvm-commits] [llvm] r123372 - in /llvm/trunk: lib/Analysis/InstructionSimplify.cpp test/Transforms/InstSimplify/2010-12-20-I1Arithmetic.ll

Chris Lattner clattner at apple.com
Thu Jan 13 13:26:29 PST 2011


On Jan 13, 2011, at 12:56 AM, Duncan Sands wrote:

> Author: baldrick
> Date: Thu Jan 13 02:56:29 2011
> New Revision: 123372
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=123372&view=rev
> Log:
> The most common simplification missed by instsimplify in unoptimized bitcode
> is "X != 0 -> X" when X is a boolean.  This occurs a lot because of the way
> llvm-gcc converts gcc's conditional expressions.  Add this, and a few other
> similar transforms for completeness.

Hi Duncan,

I don't really understand the motivation here: unoptimized code has lots of missed stuff, and instsimplify doesn't run for it, no?

In any case, this looks very familiar to code already in instcombine.  Can the instcombine code be zapped now?

-Chris

> 
> Modified:
>    llvm/trunk/lib/Analysis/InstructionSimplify.cpp
>    llvm/trunk/test/Transforms/InstSimplify/2010-12-20-I1Arithmetic.ll
> 
> Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=123372&r1=123371&r2=123372&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
> +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Thu Jan 13 02:56:29 2011
> @@ -938,8 +938,8 @@
>     Pred = CmpInst::getSwappedPredicate(Pred);
>   }
> 
> -  // ITy - This is the return type of the compare we're considering.
> -  const Type *ITy = GetCompareTy(LHS);
> +  const Type *ITy = GetCompareTy(LHS); // The return type.
> +  const Type *OpTy = LHS->getType();   // The operand type.
> 
>   // icmp X, X -> true/false
>   // X icmp undef -> true/false.  For example, icmp ugt %X, undef -> false
> @@ -947,40 +947,91 @@
>   if (LHS == RHS || isa<UndefValue>(RHS))
>     return ConstantInt::get(ITy, CmpInst::isTrueWhenEqual(Pred));
> 
> -  // icmp <global/alloca*/null>, <global/alloca*/null> - Global/Stack value
> -  // addresses never equal each other!  We already know that Op0 != Op1.
> -  if ((isa<GlobalValue>(LHS) || isa<AllocaInst>(LHS) ||
> -       isa<ConstantPointerNull>(LHS)) &&
> -      (isa<GlobalValue>(RHS) || isa<AllocaInst>(RHS) ||
> -       isa<ConstantPointerNull>(RHS)))
> -    return ConstantInt::get(ITy, CmpInst::isFalseWhenEqual(Pred));
> +  // Special case logic when the operands have i1 type.
> +  if (OpTy->isIntegerTy(1) || (OpTy->isVectorTy() &&
> +       cast<VectorType>(OpTy)->getElementType()->isIntegerTy(1))) {
> +    switch (Pred) {
> +    default: break;
> +    case ICmpInst::ICMP_EQ:
> +      // X == 1 -> X
> +      if (match(RHS, m_One()))
> +        return LHS;
> +      break;
> +    case ICmpInst::ICMP_NE:
> +      // X != 0 -> X
> +      if (match(RHS, m_Zero()))
> +        return LHS;
> +      break;
> +    case ICmpInst::ICMP_UGT:
> +      // X >u 0 -> X
> +      if (match(RHS, m_Zero()))
> +        return LHS;
> +      break;
> +    case ICmpInst::ICMP_UGE:
> +      // X >=u 1 -> X
> +      if (match(RHS, m_One()))
> +        return LHS;
> +      break;
> +    case ICmpInst::ICMP_SLT:
> +      // X <s 0 -> X
> +      if (match(RHS, m_Zero()))
> +        return LHS;
> +      break;
> +    case ICmpInst::ICMP_SLE:
> +      // X <=s -1 -> X
> +      if (match(RHS, m_One()))
> +        return LHS;
> +      break;
> +    }
> +  }
> 
>   // See if we are doing a comparison with a constant.
>   if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
> -    // If we have an 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.
>     switch (Pred) {
>     default: break;
> -    case ICmpInst::ICMP_ULE:
> -      if (CI->isMaxValue(false))                 // A <=u MAX -> TRUE
> -        return ConstantInt::getTrue(CI->getContext());
> -      break;
> -    case ICmpInst::ICMP_SLE:
> -      if (CI->isMaxValue(true))                  // A <=s MAX -> TRUE
> -        return ConstantInt::getTrue(CI->getContext());
> +    case ICmpInst::ICMP_UGT:
> +      if (CI->isMaxValue(false))                 // A >u MAX -> FALSE
> +        return ConstantInt::getFalse(CI->getContext());
>       break;
>     case ICmpInst::ICMP_UGE:
>       if (CI->isMinValue(false))                 // A >=u MIN -> TRUE
>         return ConstantInt::getTrue(CI->getContext());
>       break;
> +    case ICmpInst::ICMP_ULT:
> +      if (CI->isMinValue(false))                 // A <u MIN -> FALSE
> +        return ConstantInt::getFalse(CI->getContext());
> +      break;
> +    case ICmpInst::ICMP_ULE:
> +      if (CI->isMaxValue(false))                 // A <=u MAX -> TRUE
> +        return ConstantInt::getTrue(CI->getContext());
> +      break;
> +    case ICmpInst::ICMP_SGT:
> +      if (CI->isMaxValue(true))                  // A >s MAX -> FALSE
> +        return ConstantInt::getFalse(CI->getContext());
> +      break;
>     case ICmpInst::ICMP_SGE:
>       if (CI->isMinValue(true))                  // A >=s MIN -> TRUE
>         return ConstantInt::getTrue(CI->getContext());
>       break;
> +    case ICmpInst::ICMP_SLT:
> +      if (CI->isMinValue(true))                  // A <s MIN -> FALSE
> +        return ConstantInt::getFalse(CI->getContext());
> +      break;
> +    case ICmpInst::ICMP_SLE:
> +      if (CI->isMaxValue(true))                  // A <=s MAX -> TRUE
> +        return ConstantInt::getTrue(CI->getContext());
> +      break;
>     }
>   }
> 
> +  // icmp <global/alloca*/null>, <global/alloca*/null> - Global/Stack value
> +  // addresses never equal each other!  We already know that Op0 != Op1.
> +  if ((isa<GlobalValue>(LHS) || isa<AllocaInst>(LHS) ||
> +       isa<ConstantPointerNull>(LHS)) &&
> +      (isa<GlobalValue>(RHS) || isa<AllocaInst>(RHS) ||
> +       isa<ConstantPointerNull>(RHS)))
> +    return ConstantInt::get(ITy, CmpInst::isFalseWhenEqual(Pred));
> +
>   // If the comparison is with the result of a select instruction, check whether
>   // comparing with either branch of the select always yields the same value.
>   if (isa<SelectInst>(LHS) || isa<SelectInst>(RHS))
> 
> Modified: llvm/trunk/test/Transforms/InstSimplify/2010-12-20-I1Arithmetic.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/2010-12-20-I1Arithmetic.ll?rev=123372&r1=123371&r2=123372&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstSimplify/2010-12-20-I1Arithmetic.ll (original)
> +++ llvm/trunk/test/Transforms/InstSimplify/2010-12-20-I1Arithmetic.ll Thu Jan 13 02:56:29 2011
> @@ -20,3 +20,10 @@
>   ret i1 %z
> ; CHECK: ret i1 %x
> }
> +
> +define i1 @ne(i1 %x) {
> +; CHECK: @ne
> +  %z = icmp ne i1 %x, 0
> +  ret i1 %z
> +; CHECK: ret i1 %x
> +}
> 
> 
> _______________________________________________
> 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