aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/InstructionSimplify.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-07-31 04:49:18 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-07-31 04:49:18 +0000
commitcd4fbcd1bb463a1d2b99808f52c1b6b99e82ef4d (patch)
tree731086f2e2b65c67a994c9d061df63c70ec20bd4 /llvm/lib/Analysis/InstructionSimplify.cpp
parent32dbdf62bec05f18e8f2710a110fa4e7f31fdc01 (diff)
downloadllvm-cd4fbcd1bb463a1d2b99808f52c1b6b99e82ef4d.zip
llvm-cd4fbcd1bb463a1d2b99808f52c1b6b99e82ef4d.tar.gz
llvm-cd4fbcd1bb463a1d2b99808f52c1b6b99e82ef4d.tar.bz2
InstSimplify: Simplify (X - (0 - Y)) if the second sub is NUW
If the NUW bit is set for 0 - Y, we know that all values for Y other than 0 would produce a poison value. This allows us to replace (0 - Y) with 0 in the expression (X - (0 - Y)) which will ultimately leave us with X. This partially fixes PR20189. llvm-svn: 214384
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp12
1 files changed, 12 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 7a820a5..459fc92 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -676,6 +676,18 @@ static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
if (Op0 == Op1)
return Constant::getNullValue(Op0->getType());
+ // X - (0 - Y) -> X if the second sub is NUW.
+ // If Y != 0, 0 - Y is a poison value.
+ // If Y == 0, 0 - Y simplifies to 0.
+ if (BinaryOperator::isNeg(Op1)) {
+ if (const auto *BO = dyn_cast<BinaryOperator>(Op1)) {
+ assert(BO->getOpcode() == Instruction::Sub &&
+ "Expected a subtraction operator!");
+ if (BO->hasNoUnsignedWrap())
+ return Op0;
+ }
+ }
+
// (X + Y) - Z -> X + (Y - Z) or Y + (X - Z) if everything simplifies.
// For example, (X + Y) - Y -> X; (Y + X) - Y -> X
Value *X = nullptr, *Y = nullptr, *Z = Op1;