diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2017-02-09 23:13:04 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2017-02-09 23:13:04 +0000 |
| commit | f38bab73aa86e3fb2067184b1cbda0cb1675586f (patch) | |
| tree | 537ec23576d9096d23199ca9ac84c3325d9a0826 | |
| parent | 889830b1c56d2b98929c07c6baea00d0c62025e6 (diff) | |
| download | bcm5719-llvm-f38bab73aa86e3fb2067184b1cbda0cb1675586f.tar.gz bcm5719-llvm-f38bab73aa86e3fb2067184b1cbda0cb1675586f.zip | |
[InstCombine] allow (X * C2) << C1 --> X * (C2 << C1) for vectors
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.
llvm-svn: 294650
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 25 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/apint-shift.ll | 14 |
2 files changed, 26 insertions, 13 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index ab8ba9e4be0..9aa679c60e4 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -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; @@ -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; } diff --git a/llvm/test/Transforms/InstCombine/apint-shift.ll b/llvm/test/Transforms/InstCombine/apint-shift.ll index 7feec91d0c0..f339de35d77 100644 --- a/llvm/test/Transforms/InstCombine/apint-shift.ll +++ b/llvm/test/Transforms/InstCombine/apint-shift.ll @@ -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 @@ -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 |

