diff options
author | Duncan Sands <baldrick@free.fr> | 2011-01-13 08:56:29 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2011-01-13 08:56:29 +0000 |
commit | 6dc91253ab1872e118b08511a09d5c934988354e (patch) | |
tree | 810b5ba30e433923840e644ce3668854056c1187 /lib/Analysis/InstructionSimplify.cpp | |
parent | 7597212abced110723f2fee985a7d60557c092ec (diff) | |
download | external_llvm-6dc91253ab1872e118b08511a09d5c934988354e.zip external_llvm-6dc91253ab1872e118b08511a09d5c934988354e.tar.gz external_llvm-6dc91253ab1872e118b08511a09d5c934988354e.tar.bz2 |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123372 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/InstructionSimplify.cpp')
-rw-r--r-- | lib/Analysis/InstructionSimplify.cpp | 89 |
1 files changed, 70 insertions, 19 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 030d61a..b3a3aca 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -938,8 +938,8 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, 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 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, 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)) |