diff options
author | Craig Topper <craig.topper@intel.com> | 2018-05-17 16:29:52 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@intel.com> | 2018-05-17 16:29:52 +0000 |
commit | bd332588bd3997fec40447c9bc98706085145b3c (patch) | |
tree | a68ba4e461f34c0a34125e9c8389b1048565c024 /llvm/lib/Transforms | |
parent | e389ea0e3ed2164b237177d3369c0ef1a61236ae (diff) | |
download | bcm5719-llvm-bd332588bd3997fec40447c9bc98706085145b3c.tar.gz bcm5719-llvm-bd332588bd3997fec40447c9bc98706085145b3c.zip |
[InstCombine] Propagate the nsw/nuw flags from the add in the 'shifty' abs pattern to the sub in the select version.
According to alive this is valid. I'm hoping to use this to make an assumption that the sign bit is zero after this sequence. The only way it wouldn't be is if the input was INT__MIN, but by preserving the flags we can make doing this to INT_MIN UB.
The nuw flags is weird because it creates such a contradiction that the original number would have to be positive meaning we could remove the select entirely, but we don't get that far.
Differential Revision: https://reviews.llvm.org/D46988
llvm-svn: 332623
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 368402b57cb..22e7b360d0e 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2748,7 +2748,11 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { // xor (add A, B), B ; add -1 and flip bits if negative // --> (A < 0) ? -A : A Value *Cmp = Builder.CreateICmpSLT(A, ConstantInt::getNullValue(Ty)); - return SelectInst::Create(Cmp, Builder.CreateNeg(A), A); + // Copy the nuw/nsw flags from the add to the negate. + auto *Add = cast<BinaryOperator>(Op0); + Value *Neg = Builder.CreateNeg(A, "", Add->hasNoUnsignedWrap(), + Add->hasNoSignedWrap()); + return SelectInst::Create(Cmp, Neg, A); } // Eliminate a bitwise 'not' op of 'not' min/max by inverting the min/max: |