summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorRoman Lebedev <lebedev.ri@gmail.com>2019-10-20 20:52:06 +0000
committerRoman Lebedev <lebedev.ri@gmail.com>2019-10-20 20:52:06 +0000
commit7015a5c54b53d8d2297a3aa38bc32aab167bdcfc (patch)
treed1f8a01d1cb0f0bd83f059db0574c5b6c0df9b1b /llvm/lib/Transforms
parentf7aec25d4fb193c2efb5c8bdcecd6d0611183bcc (diff)
downloadbcm5719-llvm-7015a5c54b53d8d2297a3aa38bc32aab167bdcfc.tar.gz
bcm5719-llvm-7015a5c54b53d8d2297a3aa38bc32aab167bdcfc.zip
[InstCombine] conditional sign-extend of high-bit-extract: 'or' pattern.
In this pattern, all the "magic" bits that we'd `add` are all high sign bits, and in the value we'd be adding to they are all unset, not unexpectedly, so we can have an `or` there: https://rise4fun.com/Alive/ups It is possible that `haveNoCommonBitsSet()` should be taught about this pattern so that we never have an `add` variant, but the reasoning would need to be recursive (because of that `select`), so i'm not really sure that would be worth it just yet. llvm-svn: 375378
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp35
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp4
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineInternal.h2
3 files changed, 23 insertions, 18 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 5d306cd8eea..77907cc995d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1097,10 +1097,11 @@ static Instruction *foldToUnsignedSaturatedAdd(BinaryOperator &I) {
return nullptr;
}
-static Instruction *
-canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
- BinaryOperator &I, InstCombiner::BuilderTy &Builder) {
+Instruction *
+InstCombiner::canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
+ BinaryOperator &I) {
assert((I.getOpcode() == Instruction::Add ||
+ I.getOpcode() == Instruction::Or ||
I.getOpcode() == Instruction::Sub) &&
"Expecting add/sub instruction");
@@ -1114,7 +1115,7 @@ canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
m_Value(Select))))
return nullptr;
- // `add` is commutative; but for `sub`, "select" *must* be on RHS.
+ // `add`/`or` is commutative; but for `sub`, "select" *must* be on RHS.
if (I.getOpcode() == Instruction::Sub && I.getOperand(1) != Select)
return nullptr;
@@ -1140,13 +1141,13 @@ canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
X->getType()->getScalarSizeInBits()))))
return nullptr;
- // Sign-extending value can be sign-extended itself if we `add` it,
- // or zero-extended if we `sub`tract it.
+ // Sign-extending value can be zero-extended if we `sub`tract it,
+ // or sign-extended otherwise.
auto SkipExtInMagic = [&I](Value *&V) {
- if (I.getOpcode() == Instruction::Add)
- match(V, m_SExtOrSelf(m_Value(V)));
- else
+ if (I.getOpcode() == Instruction::Sub)
match(V, m_ZExtOrSelf(m_Value(V)));
+ else
+ match(V, m_SExtOrSelf(m_Value(V)));
};
// Now, finally validate the sign-extending magic.
@@ -1169,7 +1170,7 @@ canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
if (!ShouldSignext)
std::swap(SignExtendingValue, Zero);
- // If we should not perform sign-extension then we must add/subtract zero.
+ // If we should not perform sign-extension then we must add/or/subtract zero.
if (!match(Zero, m_Zero()))
return nullptr;
// Otherwise, it should be some constant, left-shifted by the same NBits we
@@ -1181,10 +1182,10 @@ canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
m_Shl(m_Constant(SignExtendingValueBaseConstant),
m_ZExtOrSelf(m_Specific(NBits)))))
return nullptr;
- // If we `add`, then the constant should be all-ones, else it should be one.
- if (I.getOpcode() == Instruction::Add
- ? !match(SignExtendingValueBaseConstant, m_AllOnes())
- : !match(SignExtendingValueBaseConstant, m_One()))
+ // If we `sub`, then the constant should be one, else it should be all-ones.
+ if (I.getOpcode() == Instruction::Sub
+ ? !match(SignExtendingValueBaseConstant, m_One())
+ : !match(SignExtendingValueBaseConstant, m_AllOnes()))
return nullptr;
auto *NewAShr = BinaryOperator::CreateAShr(X, LowBitsToSkip,
@@ -1403,8 +1404,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
return V;
if (Instruction *V =
- canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
- I, Builder))
+ canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(I))
return V;
if (Instruction *SatAdd = foldToUnsignedSaturatedAdd(I))
@@ -2006,8 +2006,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
}
if (Instruction *V =
- canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
- I, Builder))
+ canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(I))
return V;
if (Instruction *Ext = narrowMathIfNoOverflow(I))
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index db5095b6fea..4a30b60ca93 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2725,6 +2725,10 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
}
}
+ if (Instruction *V =
+ canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(I))
+ return V;
+
return nullptr;
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 4519dc0bf37..74881a554c1 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -393,6 +393,8 @@ public:
Value *reassociateShiftAmtsOfTwoSameDirectionShifts(
BinaryOperator *Sh0, const SimplifyQuery &SQ,
bool AnalyzeForSignBitExtraction = false);
+ Instruction *canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
+ BinaryOperator &I);
Instruction *foldVariableSignZeroExtensionOfVariableHighBitExtract(
BinaryOperator &OldAShr);
Instruction *visitAShr(BinaryOperator &I);
OpenPOWER on IntegriCloud