From 9b66a372c8b6599ba0188fb153221b0b84a2ae70 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 3 Apr 2007 01:47:41 +0000 Subject: [PATCH] Fix PR1253 and xor2.ll:test[01] llvm-svn: 35612 --- .../Scalar/InstructionCombining.cpp | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index ae7e15db7bb..9aa65f4d453 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(Op0)) switch (LHSI->getOpcode()) { - case Instruction::And: + case Instruction::Xor: // (icmp pred (and X, XorCST), CI) + if (ConstantInt *XorCST = dyn_cast(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(LHSI->getOperand(1)) && LHSI->getOperand(0)->hasOneUse()) { ConstantInt *AndCST = cast(LHSI->getOperand(1));