diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2014-07-31 04:49:18 +0000 | 
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2014-07-31 04:49:18 +0000 | 
| commit | cd4fbcd1bb463a1d2b99808f52c1b6b99e82ef4d (patch) | |
| tree | 731086f2e2b65c67a994c9d061df63c70ec20bd4 /llvm | |
| parent | 32dbdf62bec05f18e8f2710a110fa4e7f31fdc01 (diff) | |
| download | bcm5719-llvm-cd4fbcd1bb463a1d2b99808f52c1b6b99e82ef4d.tar.gz bcm5719-llvm-cd4fbcd1bb463a1d2b99808f52c1b6b99e82ef4d.zip  | |
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')
| -rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 12 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstSimplify/AndOrXor.ll | 8 | 
2 files changed, 20 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 7a820a58f6f..459fc92bce1 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; diff --git a/llvm/test/Transforms/InstSimplify/AndOrXor.ll b/llvm/test/Transforms/InstSimplify/AndOrXor.ll index c59d6c916a6..0277d39b1fc 100644 --- a/llvm/test/Transforms/InstSimplify/AndOrXor.ll +++ b/llvm/test/Transforms/InstSimplify/AndOrXor.ll @@ -20,3 +20,11 @@ define i64 @pow2b(i32 %x) {    ret i64 %e2  ; CHECK: ret i64 %e  } + +define i32 @sub_neg_nuw(i32 %x, i32 %y) { +; CHECK-LABEL: @sub_neg_nuw( +  %neg = sub nuw i32 0, %y +  %sub = sub i32 %x, %neg +  ret i32 %sub +; CHECK: ret i32 %x +}  | 

