[llvm] r239115 - [InstCombine] Don't miscompile safe increment idiom
David Majnemer
david.majnemer at gmail.com
Thu Jun 4 16:11:30 PDT 2015
Author: majnemer
Date: Thu Jun 4 18:11:30 2015
New Revision: 239115
URL: http://llvm.org/viewvc/llvm-project?rev=239115&view=rev
Log:
[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.
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
llvm/trunk/test/Transforms/InstCombine/select.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=239115&r1=239114&r2=239115&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Thu Jun 4 18:11:30 2015
@@ -292,10 +292,28 @@ static Value *SimplifyWithOpReplaced(Val
// 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.
Modified: llvm/trunk/test/Transforms/InstCombine/select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select.ll?rev=239115&r1=239114&r2=239115&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/select.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/select.ll Thu Jun 4 18:11:30 2015
@@ -1532,3 +1532,13 @@ define i32 @test_max_of_min(i32 %a) {
%s1 = select i1 %c1, i32 %s0, i32 -1
ret i32 %s1
}
+
+define i32 @PR23757(i32 %x) {
+; CHECK-LABEL: @PR23757
+; CHECK: %[[add:.*]] = add i32 %x, 1
+; CHECK-NEXT: ret i32 %[[add]]
+ %cmp = icmp eq i32 %x, 2147483647
+ %add = add nsw i32 %x, 1
+ %sel = select i1 %cmp, i32 -2147483648, i32 %add
+ ret i32 %sel
+}
More information about the llvm-commits
mailing list