summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-01-21 16:14:51 +0000
committerSanjay Patel <spatel@rotateright.com>2018-01-21 16:14:51 +0000
commit9530f1886433d77bc203c366915a9ab3160c7efc (patch)
tree7713b04c77141e282a864a0e30e243e64ab4a143 /llvm/lib/Transforms
parent7a44e4d594c98b5998ebffc041490564953a3cb8 (diff)
downloadbcm5719-llvm-9530f1886433d77bc203c366915a9ab3160c7efc.tar.gz
bcm5719-llvm-9530f1886433d77bc203c366915a9ab3160c7efc.zip
[InstCombine] (X << Y) / X -> 1 << Y
...when the shift is known to not overflow with the matching signed-ness of the division. This closes an optimization gap caused by canonicalizing mul by power-of-2 to shl as shown in PR35709: https://bugs.llvm.org/show_bug.cgi?id=35709 Patch by Anton Bikineev! Differential Revision: https://reviews.llvm.org/D42032 llvm-svn: 323068
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp19
1 files changed, 12 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 899c4dd8fa7..6e7e11a15ae 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -891,6 +891,7 @@ bool InstCombiner::simplifyDivRemOfSelectWithZeroOp(BinaryOperator &I) {
/// @brief Common integer divide transforms
Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) {
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+ bool IsSigned = I.getOpcode() == Instruction::SDiv;
// The RHS is known non-zero.
if (Value *V = simplifyValueKnownNonZero(I.getOperand(1), *this, I)) {
@@ -908,7 +909,6 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) {
if (match(Op1, m_APInt(C2))) {
Value *X;
const APInt *C1;
- bool IsSigned = I.getOpcode() == Instruction::SDiv;
// (X / C1) / C2 -> X / (C1*C2)
if ((IsSigned && match(LHS, m_SDiv(m_Value(X), m_APInt(C1)))) ||
@@ -999,13 +999,18 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) {
return &I;
// (X - (X rem Y)) / Y -> X / Y; usually originates as ((X / Y) * Y) / Y
- Value *X = nullptr, *Z = nullptr;
- if (match(Op0, m_Sub(m_Value(X), m_Value(Z)))) { // (X - Z) / Y; Y = Op1
- bool isSigned = I.getOpcode() == Instruction::SDiv;
- if ((isSigned && match(Z, m_SRem(m_Specific(X), m_Specific(Op1)))) ||
- (!isSigned && match(Z, m_URem(m_Specific(X), m_Specific(Op1)))))
+ Value *X, *Z;
+ if (match(Op0, m_Sub(m_Value(X), m_Value(Z)))) // (X - Z) / Y; Y = Op1
+ if ((IsSigned && match(Z, m_SRem(m_Specific(X), m_Specific(Op1)))) ||
+ (!IsSigned && match(Z, m_URem(m_Specific(X), m_Specific(Op1)))))
return BinaryOperator::Create(I.getOpcode(), X, Op1);
- }
+
+ // (X << Y) / X -> 1 << Y
+ Value *Y;
+ if (IsSigned && match(Op0, m_NSWShl(m_Specific(Op1), m_Value(Y))))
+ return BinaryOperator::CreateNSWShl(ConstantInt::get(I.getType(), 1), Y);
+ if (!IsSigned && match(Op0, m_NUWShl(m_Specific(Op1), m_Value(Y))))
+ return BinaryOperator::CreateNUWShl(ConstantInt::get(I.getType(), 1), Y);
return nullptr;
}
OpenPOWER on IntegriCloud