diff options
author | Sanjay Patel <spatel@rotateright.com> | 2017-05-10 13:56:52 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2017-05-10 13:56:52 +0000 |
commit | 2e069f250a156cfaed3b334ade37a39814bd6bef (patch) | |
tree | b5e0bb8bfd6a8d0265b5d1a33eee74e2c035a563 /llvm/lib | |
parent | b7fb267ed3033fff977b40553714defa1a0b57d1 (diff) | |
download | bcm5719-llvm-2e069f250a156cfaed3b334ade37a39814bd6bef.tar.gz bcm5719-llvm-2e069f250a156cfaed3b334ade37a39814bd6bef.zip |
[InstCombine] add (ashr (shl i32 X, 31), 31), 1 --> and (not X), 1
This is another step towards favoring 'not' ops over random 'xor' in IR:
https://bugs.llvm.org/show_bug.cgi?id=32706
This transformation may have occurred in longer IR sequences using computeKnownBits,
but that could be much more expensive to calculate.
As the scalar result shows, we do not currently favor 'not' in all cases. The 'not'
created by the transform is transformed again (unnecessarily). Vectors don't have
this problem because vectors are (wrongly) excluded from several other combines.
llvm-svn: 302659
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 659b6c326c5..3709360226f 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1079,6 +1079,16 @@ static Instruction *foldAddWithConstant(BinaryOperator &Add, return new ZExtInst(Builder.CreateNUWAdd(X, NewC), Ty); } + // Shifts and add used to flip and mask off the low bit: + // add (ashr (shl i32 X, 31), 31), 1 --> and (not X), 1 + const APInt *C3; + if (*C == 1 && match(Op0, m_OneUse(m_AShr(m_Shl(m_Value(X), m_APInt(C2)), + m_APInt(C3)))) && + C2 == C3 && *C2 == Ty->getScalarSizeInBits() - 1) { + Value *NotX = Builder.CreateNot(X); + return BinaryOperator::CreateAnd(NotX, ConstantInt::get(Ty, 1)); + } + return nullptr; } |