From 16dc165046c3ed87be6f56f058a2eb6d8278ed76 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 21 Mar 2019 17:50:49 +0000 Subject: [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 --- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp') 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(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; -- cgit v1.2.3