From: Chris Lattner Date: Mon, 18 Sep 2006 05:27:43 +0000 (+0000) Subject: Implement InstCombine/cast.ll:test31. This speeds up 462.libquantum by 26%. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=e695a3bd32443aa7da9f5d699f2ad763643d0032;p=oota-llvm.git Implement InstCombine/cast.ll:test31. This speeds up 462.libquantum by 26%. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30456 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 4ed827944de..c3d6f1465eb 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -3871,12 +3871,46 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) { case Instruction::And: if (LHSI->hasOneUse() && isa(LHSI->getOperand(1)) && LHSI->getOperand(0)->hasOneUse()) { + ConstantInt *AndCST = cast(LHSI->getOperand(1)); + + // If an operand is an AND of a truncating cast, we can widen the + // and/compare to be the input width without changing the value + // produced, eliminating a cast. + if (CastInst *Cast = dyn_cast(LHSI->getOperand(0))) { + // We can do this transformation if either the AND constant does not + // have its sign bit set or if it is an equality comparison. + // Extending a relational comparison when we're checking the sign + // bit would not work. + if (Cast->hasOneUse() && Cast->isTruncIntCast() && + (I.isEquality() || + (AndCST->getZExtValue() == (uint64_t)AndCST->getSExtValue()) && + (CI->getZExtValue() == (uint64_t)CI->getSExtValue()))) { + ConstantInt *NewCST; + ConstantInt *NewCI; + if (Cast->getOperand(0)->getType()->isSigned()) { + NewCST = ConstantSInt::get(Cast->getOperand(0)->getType(), + AndCST->getZExtValue()); + NewCI = ConstantSInt::get(Cast->getOperand(0)->getType(), + CI->getZExtValue()); + } else { + NewCST = ConstantUInt::get(Cast->getOperand(0)->getType(), + AndCST->getZExtValue()); + NewCI = ConstantUInt::get(Cast->getOperand(0)->getType(), + CI->getZExtValue()); + } + Instruction *NewAnd = + BinaryOperator::createAnd(Cast->getOperand(0), NewCST, + LHSI->getName()); + InsertNewInstBefore(NewAnd, I); + return new SetCondInst(I.getOpcode(), NewAnd, NewCI); + } + } + // If this is: (X >> C1) & C2 != C3 (where any shift and any compare // could exist), turn it into (X & (C2 << C1)) != (C3 << C1). This // happens a LOT in code produced by the C front-end, for bitfield // access. ShiftInst *Shift = dyn_cast(LHSI->getOperand(0)); - Constant *AndCST = cast(LHSI->getOperand(1)); // Check to see if there is a noop-cast between the shift and the and. if (!Shift) { @@ -3962,11 +3996,12 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) { "tmp"); } else { // Make sure we insert a logical shift. + Constant *NewAndCST = AndCST; if (AndCST->getType()->isSigned()) - AndCST = ConstantExpr::getCast(AndCST, + NewAndCST = ConstantExpr::getCast(AndCST, AndCST->getType()->getUnsignedVersion()); - NS = new ShiftInst(Instruction::Shr, AndCST, Shift->getOperand(1), - "tmp"); + NS = new ShiftInst(Instruction::Shr, NewAndCST, + Shift->getOperand(1), "tmp"); } InsertNewInstBefore(cast(NS), I);