[InstCombine] Don't miscompile safe increment idiom
authorDavid Majnemer <david.majnemer@gmail.com>
Thu, 4 Jun 2015 23:11:30 +0000 (23:11 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Thu, 4 Jun 2015 23:11:30 +0000 (23:11 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239115 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineSelect.cpp
test/Transforms/InstCombine/select.ll

index d2fbcdd39915c8d0cba67be02aa9e66945becba7..4dec1542495b9ecec109f9a631b7684509b1a620 100644 (file)
@@ -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.
index e4bc96cff1764d419ceb279090bc0a956b2a2c89..b05f2ca2c4c7f6bb7807039c00d7c40c97f3f649 100644 (file)
@@ -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
+}