aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-06-04 23:11:30 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-06-04 23:11:30 +0000
commit00f7d9ecc8229b0dd36d362f82b4f09869d12e71 (patch)
tree26d591e319629432c7a77f4ce15b1470ba6557b4 /llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
parent70d18df18fab3d9d73b724b1042abaa536289bbe (diff)
downloadllvm-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.cpp24
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.