X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FInstructionSimplify.cpp;h=459fc92bce1a856a2d621b6aedc24c76c18c2d1a;hb=25529b337f75a4b9b174592e2c95136e781bd824;hp=fd7a4de6903786b7ef7c44093799a1a0c57bb32c;hpb=312646b71e415bb543ea1c143cca5b9009364b0d;p=oota-llvm.git diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index fd7a4de6903..459fc92bce1 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/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(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; @@ -1346,6 +1358,11 @@ static Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact, cast(Op0)->hasNoSignedWrap()) return X; + // Arithmetic shifting an all-sign-bit value is a no-op. + unsigned NumSignBits = ComputeNumSignBits(Op0, Q.DL); + if (NumSignBits == Op0->getType()->getScalarSizeInBits()) + return Op0; + return nullptr; }