diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-08-22 19:00:43 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-11-13 20:39:49 +0000 |
commit | fe6060f10f634930ff71b7c50291ddc610da2475 (patch) | |
tree | 1483580c790bd4d27b6500a7542b5ee00534d3cc /contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | |
parent | b61bce17f346d79cecfd8f195a64b10f77be43b1 (diff) | |
parent | 344a3780b2e33f6ca763666c380202b18aab72a3 (diff) | |
download | src-fe6060f10f634930ff71b7c50291ddc610da2475.tar.gz src-fe6060f10f634930ff71b7c50291ddc610da2475.zip |
Merge llvm-project main llvmorg-13-init-16847-g88e66fa60ae5
This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and
openmp to llvmorg-13-init-16847-g88e66fa60ae5, the last commit before
the upstream release/13.x branch was created.
PR: 258209
MFC after: 2 weeks
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index 127bf8080959..ca5e473fdecb 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -1137,11 +1137,23 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) { } } - // lshr i32 (X -nsw Y), 31 --> zext (X < Y) Value *Y; - if (ShAmt == BitWidth - 1 && - match(Op0, m_OneUse(m_NSWSub(m_Value(X), m_Value(Y))))) - return new ZExtInst(Builder.CreateICmpSLT(X, Y), Ty); + if (ShAmt == BitWidth - 1) { + // lshr i32 or(X,-X), 31 --> zext (X != 0) + if (match(Op0, m_OneUse(m_c_Or(m_Neg(m_Value(X)), m_Deferred(X))))) + return new ZExtInst(Builder.CreateIsNotNull(X), Ty); + + // lshr i32 (X -nsw Y), 31 --> zext (X < Y) + if (match(Op0, m_OneUse(m_NSWSub(m_Value(X), m_Value(Y))))) + return new ZExtInst(Builder.CreateICmpSLT(X, Y), Ty); + + // Check if a number is negative and odd: + // lshr i32 (srem X, 2), 31 --> and (X >> 31), X + if (match(Op0, m_OneUse(m_SRem(m_Value(X), m_SpecificInt(2))))) { + Value *Signbit = Builder.CreateLShr(X, ShAmt); + return BinaryOperator::CreateAnd(Signbit, X); + } + } if (match(Op0, m_LShr(m_Value(X), m_APInt(ShOp1)))) { unsigned AmtSum = ShAmt + ShOp1->getZExtValue(); @@ -1151,6 +1163,16 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) { return BinaryOperator::CreateLShr(X, ConstantInt::get(Ty, AmtSum)); } + // Look for a "splat" mul pattern - it replicates bits across each half of + // a value, so a right shift is just a mask of the low bits: + // lshr i32 (mul nuw X, Pow2+1), 16 --> and X, Pow2-1 + // TODO: Generalize to allow more than just half-width shifts? + const APInt *MulC; + if (match(Op0, m_NUWMul(m_Value(X), m_APInt(MulC))) && + ShAmt * 2 == BitWidth && (*MulC - 1).isPowerOf2() && + MulC->logBase2() == ShAmt) + return BinaryOperator::CreateAnd(X, ConstantInt::get(Ty, *MulC - 2)); + // If the shifted-out value is known-zero, then this is an exact shift. if (!I.isExact() && MaskedValueIsZero(Op0, APInt::getLowBitsSet(BitWidth, ShAmt), 0, &I)) { @@ -1305,11 +1327,16 @@ Instruction *InstCombinerImpl::visitAShr(BinaryOperator &I) { return new SExtInst(NewSh, Ty); } - // ashr i32 (X -nsw Y), 31 --> sext (X < Y) - Value *Y; - if (ShAmt == BitWidth - 1 && - match(Op0, m_OneUse(m_NSWSub(m_Value(X), m_Value(Y))))) - return new SExtInst(Builder.CreateICmpSLT(X, Y), Ty); + if (ShAmt == BitWidth - 1) { + // ashr i32 or(X,-X), 31 --> sext (X != 0) + if (match(Op0, m_OneUse(m_c_Or(m_Neg(m_Value(X)), m_Deferred(X))))) + return new SExtInst(Builder.CreateIsNotNull(X), Ty); + + // ashr i32 (X -nsw Y), 31 --> sext (X < Y) + Value *Y; + if (match(Op0, m_OneUse(m_NSWSub(m_Value(X), m_Value(Y))))) + return new SExtInst(Builder.CreateICmpSLT(X, Y), Ty); + } // If the shifted-out value is known-zero, then this is an exact shift. if (!I.isExact() && @@ -1326,5 +1353,14 @@ Instruction *InstCombinerImpl::visitAShr(BinaryOperator &I) { if (MaskedValueIsZero(Op0, APInt::getSignMask(BitWidth), 0, &I)) return BinaryOperator::CreateLShr(Op0, Op1); + // ashr (xor %x, -1), %y --> xor (ashr %x, %y), -1 + Value *X; + if (match(Op0, m_OneUse(m_Not(m_Value(X))))) { + // Note that we must drop 'exact'-ness of the shift! + // Note that we can't keep undef's in -1 vector constant! + auto *NewAShr = Builder.CreateAShr(X, Op1, Op0->getName() + ".not"); + return BinaryOperator::CreateNot(NewAShr); + } + return nullptr; } |