Skip to content

Commit

Permalink
[InstCombine] allow (X * C2) << C1 --> X * (C2 << C1) for vectors
Browse files Browse the repository at this point in the history
This fold already existed for vectors but only when 'C1' was a splat
constant (but 'C2' could be any constant). 

There were no tests for any vector constants, so I'm adding a test
that shows non-splat constants for both operands.  


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294650 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
rotateright committed Feb 9, 2017
1 parent 54ad54e commit 49a435a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 13 deletions.
25 changes: 12 additions & 13 deletions lib/Transforms/InstCombine/InstCombineShifts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,13 +335,6 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, Constant *Op1,
assert(!Op1C->uge(TypeBits) &&
"Shift over the type width should have been removed already");

// ((X*C1) << C2) == (X * (C1 << C2))
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0))
if (BO->getOpcode() == Instruction::Mul && isLeftShift)
if (Constant *BOOp = dyn_cast<Constant>(BO->getOperand(1)))
return BinaryOperator::CreateMul(BO->getOperand(0),
ConstantExpr::getShl(BOOp, Op1));

if (Instruction *FoldedShift = foldOpWithConstantIntoOperand(I))
return FoldedShift;

Expand Down Expand Up @@ -604,12 +597,18 @@ Instruction *InstCombiner::visitShl(BinaryOperator &I) {
}
}

// (C1 << A) << C2 -> (C1 << C2) << A
Constant *C1, *C2;
Value *A;
if (match(Op0, m_OneUse(m_Shl(m_Constant(C1), m_Value(A)))) &&
match(Op1, m_Constant(C2)))
return BinaryOperator::CreateShl(ConstantExpr::getShl(C1, C2), A);
Constant *C1;
if (match(Op1, m_Constant(C1))) {
Constant *C2;
Value *X;
// (C2 << X) << C1 --> (C2 << C1) << X
if (match(Op0, m_OneUse(m_Shl(m_Constant(C2), m_Value(X)))))
return BinaryOperator::CreateShl(ConstantExpr::getShl(C2, C1), X);

// (X * C2) << C1 --> X * (C2 << C1)
if (match(Op0, m_Mul(m_Value(X), m_Constant(C2))))
return BinaryOperator::CreateMul(X, ConstantExpr::getShl(C2, C1));
}

return nullptr;
}
Expand Down
14 changes: 14 additions & 0 deletions test/Transforms/InstCombine/apint-shift.ll
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ define i55 @test6(i55 %A) {
ret i55 %C
}

; (X * C2) << C1 --> X * (C2 << C1)

define i55 @test6a(i55 %A) {
; CHECK-LABEL: @test6a(
; CHECK-NEXT: [[C:%.*]] = mul i55 %A, 6
Expand All @@ -73,6 +75,18 @@ define i55 @test6a(i55 %A) {
ret i55 %C
}

; (X * C2) << C1 --> X * (C2 << C1)

define <2 x i55> @test6a_vec(<2 x i55> %A) {
; CHECK-LABEL: @test6a_vec(
; CHECK-NEXT: [[C:%.*]] = mul <2 x i55> %A, <i55 6, i55 48>
; CHECK-NEXT: ret <2 x i55> [[C]]
;
%B = mul <2 x i55> %A, <i55 3, i55 12>
%C = shl <2 x i55> %B, <i55 1, i55 2>
ret <2 x i55> %C
}

define i29 @test7(i8 %X) {
; CHECK-LABEL: @test7(
; CHECK-NEXT: ret i29 -1
Expand Down

0 comments on commit 49a435a

Please sign in to comment.