diff options
author | Craig Topper <craig.topper@intel.com> | 2019-03-21 17:50:49 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@intel.com> | 2019-03-21 17:50:49 +0000 |
commit | 16dc165046c3ed87be6f56f058a2eb6d8278ed76 (patch) | |
tree | 77f9edc342bf83481df8551c0bba868445b41c04 /llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | |
parent | 1383340422aac36dc5aa6d181bfb7188873b8909 (diff) | |
download | bcm5719-llvm-16dc165046c3ed87be6f56f058a2eb6d8278ed76.tar.gz bcm5719-llvm-16dc165046c3ed87be6f56f058a2eb6d8278ed76.zip |
[InstCombine] Don't transform ((C1 OP zext(X)) & C2) -> zext((C1 OP X) & C2) if either zext or OP has another use.
If they have other users we'll just end up increasing the instruction count.
We might be able to weaken this to only one of them having a single use if we can prove that the and will be removed.
Fixes PR41164.
Differential Revision: https://reviews.llvm.org/D59630
llvm-svn: 356690
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 99f17312bb4..31cf6386918 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1664,6 +1664,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) { // ((C1 OP zext(X)) & C2) -> zext((C1-X) & C2) if C2 fits in the bitwidth // of X and OP behaves well when given trunc(C1) and X. + // TODO: Do this for vectors by using m_APInt isntead of m_ConstantInt. switch (Op0I->getOpcode()) { default: break; @@ -1674,7 +1675,10 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { case Instruction::Sub: Value *X; ConstantInt *C1; - if (match(Op0I, m_c_BinOp(m_ZExt(m_Value(X)), m_ConstantInt(C1)))) { + // TODO: The one use restrictions could be relaxed a little if the AND + // is going to be removed. + if (match(Op0I, m_OneUse(m_c_BinOp(m_OneUse(m_ZExt(m_Value(X))), + m_ConstantInt(C1))))) { if (AndRHSMask.isIntN(X->getType()->getScalarSizeInBits())) { auto *TruncC1 = ConstantExpr::getTrunc(C1, X->getType()); Value *BinOp; |