diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-06-04 23:11:30 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-06-04 23:11:30 +0000 |
commit | 00f7d9ecc8229b0dd36d362f82b4f09869d12e71 (patch) | |
tree | 26d591e319629432c7a77f4ce15b1470ba6557b4 /llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | |
parent | 70d18df18fab3d9d73b724b1042abaa536289bbe (diff) | |
download | llvm-00f7d9ecc8229b0dd36d362f82b4f09869d12e71.zip llvm-00f7d9ecc8229b0dd36d362f82b4f09869d12e71.tar.gz llvm-00f7d9ecc8229b0dd36d362f82b4f09869d12e71.tar.bz2 |
[InstCombine] Don't miscompile safe increment idiom
We cleverly handle cases where computation done in one argument of a select
instruction is suitable for the other operand, thus obviating the need
of the select and the comparison. However, the other operand cannot
have flags.
This fixes PR23757.
llvm-svn: 239115
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index d2fbcdd..4dec154 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -292,10 +292,28 @@ static Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp, // If this is a binary operator, try to simplify it with the replaced op. if (BinaryOperator *B = dyn_cast<BinaryOperator>(I)) { + Value *Simplified = nullptr; if (B->getOperand(0) == Op) - return SimplifyBinOp(B->getOpcode(), RepOp, B->getOperand(1), DL, TLI); - if (B->getOperand(1) == Op) - return SimplifyBinOp(B->getOpcode(), B->getOperand(0), RepOp, DL, TLI); + Simplified = + SimplifyBinOp(B->getOpcode(), RepOp, B->getOperand(1), DL, TLI); + if (!Simplified && B->getOperand(1) == Op) + Simplified = + SimplifyBinOp(B->getOpcode(), B->getOperand(0), RepOp, DL, TLI); + if (Simplified) { + // Consider: + // %cmp = icmp eq i32 %x, 2147483647 + // %add = add nsw i32 %x, 1 + // %sel = select i1 %cmp, i32 -2147483648, i32 %add + // + // We can't replace %sel with %add unless we strip away the flags. + if (isa<OverflowingBinaryOperator>(B)) { + B->setHasNoSignedWrap(false); + B->setHasNoUnsignedWrap(false); + } + if (isa<PossiblyExactOperator>(B)) + B->setIsExact(false); + } + return Simplified; } // Same for CmpInsts. |