diff options
author | Chris Lattner <sabre@nondot.org> | 2007-04-03 01:47:41 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-04-03 01:47:41 +0000 |
commit | 44ad43033ee94109accee4286a36d782ee6b96b1 (patch) | |
tree | b1d638f9913ef9922d6e635ed0c52a326ad5e843 /lib/Transforms/Scalar | |
parent | 08a3fbe42ed89b2a543581f281c31a10ca223bb0 (diff) | |
download | external_llvm-44ad43033ee94109accee4286a36d782ee6b96b1.zip external_llvm-44ad43033ee94109accee4286a36d782ee6b96b1.tar.gz external_llvm-44ad43033ee94109accee4286a36d782ee6b96b1.tar.bz2 |
Fix PR1253 and xor2.ll:test[01]
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35612 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar')
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index ae7e15d..9aa65f4 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -4714,7 +4714,36 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { // instruction can be folded into the icmp if (Instruction *LHSI = dyn_cast<Instruction>(Op0)) switch (LHSI->getOpcode()) { - case Instruction::And: + case Instruction::Xor: // (icmp pred (and X, XorCST), CI) + if (ConstantInt *XorCST = dyn_cast<ConstantInt>(LHSI->getOperand(1))) { + // If this is a comparison that tests the signbit (X < 0) or (x > -1), + // fold the xor. + if (I.getPredicate() == ICmpInst::ICMP_SLT && CI->isZero() || + I.getPredicate() == ICmpInst::ICMP_SGT && CI->isAllOnesValue()) { + Value *CompareVal = LHSI->getOperand(0); + + // If the sign bit of the XorCST is not set, there is no change to + // the operation, just stop using the Xor. + if (!XorCST->getValue().isNegative()) { + I.setOperand(0, CompareVal); + AddToWorkList(LHSI); + return &I; + } + + // Was the old condition true if the operand is positive? + bool isTrueIfPositive = I.getPredicate() == ICmpInst::ICMP_SGT; + + // If so, the new one isn't. + isTrueIfPositive ^= true; + + if (isTrueIfPositive) + return new ICmpInst(ICmpInst::ICMP_SGT, CompareVal, SubOne(CI)); + else + return new ICmpInst(ICmpInst::ICMP_SLT, CompareVal, AddOne(CI)); + } + } + break; + case Instruction::And: // (icmp pred (and X, AndCST), CI) if (LHSI->hasOneUse() && isa<ConstantInt>(LHSI->getOperand(1)) && LHSI->getOperand(0)->hasOneUse()) { ConstantInt *AndCST = cast<ConstantInt>(LHSI->getOperand(1)); |