diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2019-10-20 20:52:06 +0000 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2019-10-20 20:52:06 +0000 |
commit | 7015a5c54b53d8d2297a3aa38bc32aab167bdcfc (patch) | |
tree | d1f8a01d1cb0f0bd83f059db0574c5b6c0df9b1b /llvm/lib/Transforms | |
parent | f7aec25d4fb193c2efb5c8bdcecd6d0611183bcc (diff) | |
download | bcm5719-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.cpp | 35 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineInternal.h | 2 |
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); |