aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Scalar
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-04-03 01:47:41 +0000
committerChris Lattner <sabre@nondot.org>2007-04-03 01:47:41 +0000
commit44ad43033ee94109accee4286a36d782ee6b96b1 (patch)
treeb1d638f9913ef9922d6e635ed0c52a326ad5e843 /lib/Transforms/Scalar
parent08a3fbe42ed89b2a543581f281c31a10ca223bb0 (diff)
downloadexternal_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.cpp31
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));