From 1fdfae05b0a4356d1ed0633bf3d6cdc6eba2e173 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 24 Dec 2011 17:31:38 +0000 Subject: InstCombine: Canonicalize (2^n)-1 - x into (2^n)-1 ^ x iff x is known to be smaller than 2^n. This has the obvious advantage of being commutable and is always a win on x86 because const - x wastes a register there. On less weird architectures this may lead to a regression because other arithmetic doesn't fuse with it anymore. I'll address that problem in a followup. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147254 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp') diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 5cd9a4b..4c72020 100644 --- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -567,9 +567,20 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, LHSKnownZero, LHSKnownOne, Depth+1)) return I; } + // Otherwise just hand the sub off to ComputeMaskedBits to fill in // the known zeros and ones. ComputeMaskedBits(V, DemandedMask, KnownZero, KnownOne, Depth); + + // Turn this into a xor if LHS is 2^n-1 and the remaining bits are known + // zero. + if (ConstantInt *C0 = dyn_cast(I->getOperand(0))) { + APInt I0 = C0->getValue(); + if ((I0 + 1).isPowerOf2() && (I0 | KnownZero).isAllOnesValue()) { + Instruction *Xor = BinaryOperator::CreateXor(I->getOperand(1), C0); + return InsertNewInstWith(Xor, *I); + } + } break; case Instruction::Shl: if (ConstantInt *SA = dyn_cast(I->getOperand(1))) { -- cgit v1.1 From 148fd55ef3b47e224539eac7342c936bbf138ed5 Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Wed, 4 Jan 2012 09:28:29 +0000 Subject: Teach instcombine all sorts of great stuff about shifts that have exact, nuw or nsw bits on them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147528 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp') diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 4c72020..91a48a8 100644 --- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -682,8 +682,9 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, if (BitWidth <= ShiftAmt || KnownZero[BitWidth-ShiftAmt-1] || (HighBits & ~DemandedMask) == HighBits) { // Perform the logical shift right. - Instruction *NewVal = BinaryOperator::CreateLShr( - I->getOperand(0), SA, I->getName()); + BinaryOperator *NewVal = BinaryOperator::CreateLShr(I->getOperand(0), + SA, I->getName()); + NewVal->setIsExact(cast(I)->isExact()); return InsertNewInstWith(NewVal, *I); } else if ((KnownOne & SignBit) != 0) { // New bits are known one. KnownOne |= HighBits; -- cgit v1.1 From bec2d03c4d774e67ebc586b3a00792d996f26140 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 24 Jan 2012 14:31:22 +0000 Subject: basic instcombine support for CDS. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148806 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineSimplifyDemanded.cpp | 35 +++++++++++++++------- 1 file changed, 24 insertions(+), 11 deletions(-) (limited to 'lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp') diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 91a48a8..ed94425 100644 --- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -855,23 +855,36 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, return NewCP != CV ? NewCP : 0; } - if (isa(V)) { - // Simplify the CAZ to a ConstantVector where the non-demanded elements are - // set to undef. + if (ConstantDataVector *CDV = dyn_cast(V)) { + // Check if this is identity. If so, return 0 since we are not simplifying + // anything. + if (DemandedElts.isAllOnesValue()) + return 0; + + // Simplify to a ConstantVector where the non-demanded elements are undef. + Constant *Undef = UndefValue::get(CDV->getElementType()); + SmallVector Elts; + for (unsigned i = 0; i != VWidth; ++i) + Elts.push_back(DemandedElts[i] ? CDV->getElementAsConstant(i) : Undef); + UndefElts = DemandedElts ^ EltMask; + return ConstantVector::get(Elts); + + } + + if (ConstantAggregateZero *CAZ = dyn_cast(V)) { // Check if this is identity. If so, return 0 since we are not simplifying // anything. if (DemandedElts.isAllOnesValue()) return 0; - Type *EltTy = cast(V->getType())->getElementType(); - Constant *Zero = Constant::getNullValue(EltTy); - Constant *Undef = UndefValue::get(EltTy); - std::vector Elts; - for (unsigned i = 0; i != VWidth; ++i) { - Constant *Elt = DemandedElts[i] ? Zero : Undef; - Elts.push_back(Elt); - } + // Simplify the CAZ to a ConstantVector where the non-demanded elements are + // set to undef. + Constant *Zero = CAZ->getSequentialElement(); + Constant *Undef = UndefValue::get(Zero->getType()); + SmallVector Elts; + for (unsigned i = 0; i != VWidth; ++i) + Elts.push_back(DemandedElts[i] ? Zero : Undef); UndefElts = DemandedElts ^ EltMask; return ConstantVector::get(Elts); } -- cgit v1.1 From 4ca829e89567f002fc74eb0e3e532a7c7662e031 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 25 Jan 2012 06:02:56 +0000 Subject: use ConstantVector::getSplat in a few places. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148929 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp') diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index ed94425..7b1617d 100644 --- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -851,8 +851,8 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, } // If we changed the constant, return it. - Constant *NewCP = ConstantVector::get(Elts); - return NewCP != CV ? NewCP : 0; + Constant *NewCV = ConstantVector::get(Elts); + return NewCV != CV ? NewCV : 0; } if (ConstantDataVector *CDV = dyn_cast(V)) { -- cgit v1.1 From a1f00f4d488eb5daff52faaf99c62ee652fd3b85 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 25 Jan 2012 06:48:06 +0000 Subject: use Constant::getAggregateElement to simplify a bunch of code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148934 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineSimplifyDemanded.cpp | 64 ++++++++-------------- 1 file changed, 22 insertions(+), 42 deletions(-) (limited to 'lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp') diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 7b1617d..6873d15 100644 --- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -834,59 +834,39 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, } UndefElts = 0; - if (ConstantVector *CV = dyn_cast(V)) { + + // Handle ConstantAggregateZero, ConstantVector, ConstantDataSequential. + if (Constant *C = dyn_cast(V)) { + // Check if this is identity. If so, return 0 since we are not simplifying + // anything. + if (DemandedElts.isAllOnesValue()) + return 0; + Type *EltTy = cast(V->getType())->getElementType(); Constant *Undef = UndefValue::get(EltTy); - - std::vector Elts; - for (unsigned i = 0; i != VWidth; ++i) + + SmallVector Elts; + for (unsigned i = 0; i != VWidth; ++i) { if (!DemandedElts[i]) { // If not demanded, set to undef. Elts.push_back(Undef); UndefElts.setBit(i); - } else if (isa(CV->getOperand(i))) { // Already undef. + continue; + } + + Constant *Elt = C->getAggregateElement(i); + if (Elt == 0) return 0; + + if (isa(Elt)) { // Already undef. Elts.push_back(Undef); UndefElts.setBit(i); } else { // Otherwise, defined. - Elts.push_back(CV->getOperand(i)); + Elts.push_back(Elt); } - + } + // If we changed the constant, return it. Constant *NewCV = ConstantVector::get(Elts); - return NewCV != CV ? NewCV : 0; - } - - if (ConstantDataVector *CDV = dyn_cast(V)) { - // Check if this is identity. If so, return 0 since we are not simplifying - // anything. - if (DemandedElts.isAllOnesValue()) - return 0; - - // Simplify to a ConstantVector where the non-demanded elements are undef. - Constant *Undef = UndefValue::get(CDV->getElementType()); - - SmallVector Elts; - for (unsigned i = 0; i != VWidth; ++i) - Elts.push_back(DemandedElts[i] ? CDV->getElementAsConstant(i) : Undef); - UndefElts = DemandedElts ^ EltMask; - return ConstantVector::get(Elts); - - } - - if (ConstantAggregateZero *CAZ = dyn_cast(V)) { - // Check if this is identity. If so, return 0 since we are not simplifying - // anything. - if (DemandedElts.isAllOnesValue()) - return 0; - - // Simplify the CAZ to a ConstantVector where the non-demanded elements are - // set to undef. - Constant *Zero = CAZ->getSequentialElement(); - Constant *Undef = UndefValue::get(Zero->getType()); - SmallVector Elts; - for (unsigned i = 0; i != VWidth; ++i) - Elts.push_back(DemandedElts[i] ? Zero : Undef); - UndefElts = DemandedElts ^ EltMask; - return ConstantVector::get(Elts); + return NewCV != C ? NewCV : 0; } // Limit search depth. -- cgit v1.1 From a78fa8cc2dd6d2ffe5e4fe605f38aae7b3d2fb7a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 27 Jan 2012 03:08:05 +0000 Subject: continue making the world safe for ConstantDataVector. At this point, we should (theoretically optimize and codegen ConstantDataVector as well as ConstantVector. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149116 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp') diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 6873d15..61a8e5b 100644 --- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -982,7 +982,7 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, if (NewUndefElts) { // Add additional discovered undefs. - std::vector Elts; + SmallVector Elts; for (unsigned i = 0; i < VWidth; ++i) { if (UndefElts[i]) Elts.push_back(UndefValue::get(Type::getInt32Ty(I->getContext()))); -- cgit v1.1