From 364359e4fc0a0673574a8b4e8a04039abbe9ce5e Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 8 Aug 2017 20:14:11 +0000 Subject: [InstCombine] Support pulling left shifts through a subtract with constant LHS We already support pulling through an add with constant RHS. We can do the same for subtract. Differential Revision: https://reviews.llvm.org/D36443 llvm-svn: 310407 --- llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'llvm/lib') diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index 5f21666f65a..098079abdf7 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -510,6 +510,20 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, Constant *Op1, NewRHS); } } + + // If the operand is a subtract with a constant LHS, and the shift + // is the only use, we can pull it out of the shift. + // This folds (shl (sub C1, X), C2) -> (sub (C1 << C2), (shl X, C2)) + if (isLeftShift && Op0BO->getOpcode() == Instruction::Sub && + match(Op0BO->getOperand(0), m_APInt(Op0C))) { + Constant *NewRHS = ConstantExpr::get(I.getOpcode(), + cast(Op0BO->getOperand(0)), Op1); + + Value *NewShift = Builder.CreateShl(Op0BO->getOperand(1), Op1); + NewShift->takeName(Op0BO); + + return BinaryOperator::CreateSub(NewRHS, NewShift); + } } } -- cgit v1.2.3