[llvm] r367695 - [InstCombine] fold cmp+select using select operand equivalence

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 2 10:39:32 PDT 2019


Author: spatel
Date: Fri Aug  2 10:39:32 2019
New Revision: 367695

URL: http://llvm.org/viewvc/llvm-project?rev=367695&view=rev
Log:
[InstCombine] fold cmp+select using select operand equivalence

As discussed in PR42696:
https://bugs.llvm.org/show_bug.cgi?id=42696
...but won't help that case yet.

We have an odd situation where a select operand equivalence fold was
implemented in InstSimplify when it could have been done more generally
in InstCombine if we allow dropping of {nsw,nuw,exact} from a binop operand.

Here's an example:
https://rise4fun.com/Alive/Xplr

  %cmp = icmp eq i32 %x, 2147483647
  %add = add nsw i32 %x, 1
  %sel = select i1 %cmp, i32 -2147483648, i32 %add
  =>
  %sel = add i32 %x, 1

I've left the InstSimplify code in place for now, but my guess is that we'd
prefer to remove that as a follow-up to save on code duplication and
compile-time.

Differential Revision: https://reviews.llvm.org/D65576

Modified:
    llvm/trunk/lib/Analysis/InstructionSimplify.cpp
    llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
    llvm/trunk/test/Transforms/InstCombine/select-bitext-bitwise-ops.ll
    llvm/trunk/test/Transforms/InstCombine/select-obo-peo-ops.ll
    llvm/trunk/test/Transforms/InstCombine/select.ll

Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=367695&r1=367694&r2=367695&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Fri Aug  2 10:39:32 2019
@@ -3529,6 +3529,9 @@ static const Value *SimplifyWithOpReplac
     //   %sel = select i1 %cmp, i32 -2147483648, i32 %add
     //
     // We can't replace %sel with %add unless we strip away the flags.
+    // TODO: This is an unusual limitation because better analysis results in
+    //       worse simplification. InstCombine can do this fold more generally
+    //       by dropping the flags. Remove this fold to save compile-time?
     if (isa<OverflowingBinaryOperator>(B))
       if (Q.IIQ.hasNoSignedWrap(B) || Q.IIQ.hasNoUnsignedWrap(B))
         return nullptr;

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=367695&r1=367694&r2=367695&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Fri Aug  2 10:39:32 2019
@@ -1060,11 +1060,69 @@ static Instruction *canonicalizeAbsNabs(
   return &Sel;
 }
 
+static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *ReplaceOp,
+                                     const SimplifyQuery &Q) {
+  // If this is a binary operator, try to simplify it with the replaced op
+  // because we know Op and ReplaceOp are equivalant.
+  // For example: V = X + 1, Op = X, ReplaceOp = 42
+  // Simplifies as: add(42, 1) --> 43
+  if (auto *BO = dyn_cast<BinaryOperator>(V)) {
+    if (BO->getOperand(0) == Op)
+      return SimplifyBinOp(BO->getOpcode(), ReplaceOp, BO->getOperand(1), Q);
+    if (BO->getOperand(1) == Op)
+      return SimplifyBinOp(BO->getOpcode(), BO->getOperand(0), ReplaceOp, Q);
+  }
+
+  return nullptr;
+}
+
+/// If we have a select with an equality comparison, then we know the value in
+/// one of the arms of the select. See if substituting this value into an arm
+/// and simplifying the result yields the same value as the other arm.
+///
+/// To make this transform safe, we must drop poison-generating flags
+/// (nsw, etc) if we simplified to a binop because the select may be guarding
+/// that poison from propagating. If the existing binop already had no
+/// poison-generating flags, then this transform can be done by instsimplify.
+///
+/// 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.
+static Value *foldSelectValueEquivalence(SelectInst &Sel, ICmpInst &Cmp,
+                                         const SimplifyQuery &Q) {
+  if (!Cmp.isEquality())
+    return nullptr;
+
+  // Canonicalize the pattern to ICMP_EQ by swapping the select operands.
+  Value *TrueVal = Sel.getTrueValue(), *FalseVal = Sel.getFalseValue();
+  if (Cmp.getPredicate() == ICmpInst::ICMP_NE)
+    std::swap(TrueVal, FalseVal);
+
+  // Try each equivalence substitution possibility.
+  // We have an 'EQ' comparison, so the select's false value will propagate.
+  // Example:
+  // (X == 42) ? 43 : (X + 1) --> (X == 42) ? (X + 1) : (X + 1) --> X + 1
+  // (X == 42) ? (X + 1) : 43 --> (X == 42) ? (42 + 1) : 43 --> 43
+  Value *CmpLHS = Cmp.getOperand(0), *CmpRHS = Cmp.getOperand(1);
+  if (simplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, Q) == TrueVal ||
+      simplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, Q) == TrueVal ||
+      simplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, Q) == FalseVal ||
+      simplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, Q) == FalseVal) {
+    if (auto *FalseInst = dyn_cast<Instruction>(FalseVal))
+      FalseInst->dropPoisonGeneratingFlags();
+    return FalseVal;
+  }
+  return nullptr;
+}
+
 /// Visit a SelectInst that has an ICmpInst as its first operand.
 Instruction *InstCombiner::foldSelectInstWithICmp(SelectInst &SI,
                                                   ICmpInst *ICI) {
-  Value *TrueVal = SI.getTrueValue();
-  Value *FalseVal = SI.getFalseValue();
+  if (Value *V = foldSelectValueEquivalence(SI, *ICI, SQ))
+    return replaceInstUsesWith(SI, V);
 
   if (Instruction *NewSel = canonicalizeMinMaxWithConstant(SI, *ICI, Builder))
     return NewSel;
@@ -1078,6 +1136,8 @@ Instruction *InstCombiner::foldSelectIns
     return replaceInstUsesWith(SI, V);
 
   // NOTE: if we wanted to, this is where to detect integer MIN/MAX
+  Value *TrueVal = SI.getTrueValue();
+  Value *FalseVal = SI.getFalseValue();
   ICmpInst::Predicate Pred = ICI->getPredicate();
   Value *CmpLHS = ICI->getOperand(0);
   Value *CmpRHS = ICI->getOperand(1);

Modified: llvm/trunk/test/Transforms/InstCombine/select-bitext-bitwise-ops.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select-bitext-bitwise-ops.ll?rev=367695&r1=367694&r2=367695&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/select-bitext-bitwise-ops.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/select-bitext-bitwise-ops.ll Fri Aug  2 10:39:32 2019
@@ -3,13 +3,11 @@
 
 define i64 @sel_false_val_is_a_masked_shl_of_true_val1(i32 %x, i64 %y) {
 ; CHECK-LABEL: @sel_false_val_is_a_masked_shl_of_true_val1(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
-; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 60
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 15
   %2 = shl nuw nsw i32 %1, 2
@@ -39,13 +37,11 @@ define i64 @sel_false_val_is_a_masked_sh
 
 define i64 @sel_false_val_is_a_masked_lshr_of_true_val1(i32 %x, i64 %y) {
 ; CHECK-LABEL: @sel_false_val_is_a_masked_lshr_of_true_val1(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 60
-; CHECK-NEXT:    [[TMP2:%.*]] = lshr exact i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 15
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 60
   %2 = lshr i32 %1, 2
@@ -75,13 +71,11 @@ define i64 @sel_false_val_is_a_masked_ls
 
 define i64 @sel_false_val_is_a_masked_ashr_of_true_val1(i32 %x, i64 %y) {
 ; CHECK-LABEL: @sel_false_val_is_a_masked_ashr_of_true_val1(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2147483588
-; CHECK-NEXT:    [[TMP2:%.*]] = ashr exact i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = ashr i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -536870897
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, -2147483588
   %2 = ashr i32 %1, 2

Modified: llvm/trunk/test/Transforms/InstCombine/select-obo-peo-ops.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select-obo-peo-ops.ll?rev=367695&r1=367694&r2=367695&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/select-obo-peo-ops.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/select-obo-peo-ops.ll Fri Aug  2 10:39:32 2019
@@ -3,13 +3,11 @@
 
 define i64 @test_shl_nuw_nsw__all_are_safe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_shl_nuw_nsw__all_are_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
-; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 60
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 15
   %2 = shl nuw nsw i32 %1, 2
@@ -22,13 +20,11 @@ define i64 @test_shl_nuw_nsw__all_are_sa
 
 define i64 @test_shl_nuw__all_are_safe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_shl_nuw__all_are_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
-; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 60
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 15
   %2 = shl nuw i32 %1, 2
@@ -41,13 +37,11 @@ define i64 @test_shl_nuw__all_are_safe(i
 
 define i64 @test_shl_nsw__all_are_safe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_shl_nsw__all_are_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
-; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 60
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 15
   %2 = shl nsw i32 %1, 2
@@ -60,13 +54,11 @@ define i64 @test_shl_nsw__all_are_safe(i
 
 define i64 @test_shl__all_are_safe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_shl__all_are_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
-; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 60
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 15
   %2 = shl i32 %1, 2
@@ -79,13 +71,11 @@ define i64 @test_shl__all_are_safe(i32 %
 
 define i64 @test_shl_nuw_nsw__nuw_is_safe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_shl_nuw_nsw__nuw_is_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 1073741822
-; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -8
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 1073741822
   %2 = shl nuw nsw i32 %1, 2
@@ -98,13 +88,11 @@ define i64 @test_shl_nuw_nsw__nuw_is_saf
 
 define i64 @test_shl_nuw__nuw_is_safe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_shl_nuw__nuw_is_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 1073741822
-; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -8
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 1073741822
   %2 = shl nuw i32 %1, 2
@@ -117,13 +105,11 @@ define i64 @test_shl_nuw__nuw_is_safe(i3
 
 define i64 @test_shl_nsw__nuw_is_safe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_shl_nsw__nuw_is_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 1073741822
-; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -8
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 1073741822
   %2 = shl nsw i32 %1, 2
@@ -136,13 +122,11 @@ define i64 @test_shl_nsw__nuw_is_safe(i3
 
 define i64 @test_shl__nuw_is_safe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_shl__nuw_is_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 1073741822
-; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -8
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 1073741822
   %2 = shl i32 %1, 2
@@ -156,12 +140,10 @@ define i64 @test_shl__nuw_is_safe(i32 %x
 define i32 @test_shl_nuw_nsw__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_shl_nuw_nsw__nsw_is_safe(
 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X:%.*]], -83886080
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -83886079
-; CHECK-NEXT:    [[TMP3:%.*]] = shl nuw nsw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i32 -335544316, i32 [[TMP3]]
-; CHECK-NEXT:    [[TMP5:%.*]] = mul i32 [[TMP4]], [[TMP1]]
-; CHECK-NEXT:    [[TMP6:%.*]] = mul i32 [[TMP5]], [[TMP3]]
-; CHECK-NEXT:    ret i32 [[TMP6]]
+; CHECK-NEXT:    [[TMP2:%.*]] = shl nsw i32 [[TMP1]], 2
+; CHECK-NEXT:    [[TMP3:%.*]] = mul i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[TMP4:%.*]] = mul i32 [[TMP3]], [[TMP2]]
+; CHECK-NEXT:    ret i32 [[TMP4]]
 ;
   %1 = or i32 %x, -83886080
   %2 = icmp eq i32 %1, -83886079
@@ -175,12 +157,10 @@ define i32 @test_shl_nuw_nsw__nsw_is_saf
 define i32 @test_shl_nuw__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_shl_nuw__nsw_is_safe(
 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X:%.*]], -83886080
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -83886079
-; CHECK-NEXT:    [[TMP3:%.*]] = shl nuw nsw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i32 -335544316, i32 [[TMP3]]
-; CHECK-NEXT:    [[TMP5:%.*]] = mul i32 [[TMP4]], [[TMP1]]
-; CHECK-NEXT:    [[TMP6:%.*]] = mul i32 [[TMP5]], [[TMP3]]
-; CHECK-NEXT:    ret i32 [[TMP6]]
+; CHECK-NEXT:    [[TMP2:%.*]] = shl nsw i32 [[TMP1]], 2
+; CHECK-NEXT:    [[TMP3:%.*]] = mul i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[TMP4:%.*]] = mul i32 [[TMP3]], [[TMP2]]
+; CHECK-NEXT:    ret i32 [[TMP4]]
 ;
   %1 = or i32 %x, -83886080
   %2 = icmp eq i32 %1, -83886079
@@ -194,12 +174,10 @@ define i32 @test_shl_nuw__nsw_is_safe(i3
 define i32 @test_shl_nsw__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_shl_nsw__nsw_is_safe(
 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X:%.*]], -83886080
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -83886079
-; CHECK-NEXT:    [[TMP3:%.*]] = shl nsw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i32 -335544316, i32 [[TMP3]]
-; CHECK-NEXT:    [[TMP5:%.*]] = mul i32 [[TMP4]], [[TMP1]]
-; CHECK-NEXT:    [[TMP6:%.*]] = mul i32 [[TMP5]], [[TMP3]]
-; CHECK-NEXT:    ret i32 [[TMP6]]
+; CHECK-NEXT:    [[TMP2:%.*]] = shl nsw i32 [[TMP1]], 2
+; CHECK-NEXT:    [[TMP3:%.*]] = mul i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[TMP4:%.*]] = mul i32 [[TMP3]], [[TMP2]]
+; CHECK-NEXT:    ret i32 [[TMP4]]
 ;
   %1 = or i32 %x, -83886080
   %2 = icmp eq i32 %1, -83886079
@@ -213,12 +191,10 @@ define i32 @test_shl_nsw__nsw_is_safe(i3
 define i32 @test_shl__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_shl__nsw_is_safe(
 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X:%.*]], -83886080
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], -83886079
-; CHECK-NEXT:    [[TMP3:%.*]] = shl nsw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP2]], i32 -335544316, i32 [[TMP3]]
-; CHECK-NEXT:    [[TMP5:%.*]] = mul i32 [[TMP4]], [[TMP1]]
-; CHECK-NEXT:    [[TMP6:%.*]] = mul i32 [[TMP5]], [[TMP3]]
-; CHECK-NEXT:    ret i32 [[TMP6]]
+; CHECK-NEXT:    [[TMP2:%.*]] = shl nsw i32 [[TMP1]], 2
+; CHECK-NEXT:    [[TMP3:%.*]] = mul i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[TMP4:%.*]] = mul i32 [[TMP3]], [[TMP2]]
+; CHECK-NEXT:    ret i32 [[TMP4]]
 ;
   %1 = or i32 %x, -83886080
   %2 = icmp eq i32 %1, -83886079
@@ -232,13 +208,11 @@ define i32 @test_shl__nsw_is_safe(i32 %x
 
 define i64 @test_shl_nuw_nsw__none_are_safe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_shl_nuw_nsw__none_are_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
-; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -8
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 4294967294
   %2 = shl nuw nsw i32 %1, 2
@@ -251,13 +225,11 @@ define i64 @test_shl_nuw_nsw__none_are_s
 
 define i64 @test_shl_nuw__none_are_safe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_shl_nuw__none_are_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
-; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -8
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 4294967294
   %2 = shl nuw i32 %1, 2
@@ -270,13 +242,11 @@ define i64 @test_shl_nuw__none_are_safe(
 
 define i64 @test_shl_nsw__none_are_safe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_shl_nsw__none_are_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
-; CHECK-NEXT:    [[TMP2:%.*]] = shl nsw i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -8
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 4294967294
   %2 = shl nsw i32 %1, 2
@@ -306,13 +276,11 @@ define i64 @test_shl__none_are_safe(i32
 
 define i64 @test_lshr_exact__exact_is_safe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_lshr_exact__exact_is_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 60
-; CHECK-NEXT:    [[TMP2:%.*]] = lshr exact i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 15
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 60
   %2 = lshr exact i32 %1, 2
@@ -325,13 +293,11 @@ define i64 @test_lshr_exact__exact_is_sa
 
 define i64 @test_lshr__exact_is_safe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_lshr__exact_is_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 60
-; CHECK-NEXT:    [[TMP2:%.*]] = lshr exact i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 15
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 60
   %2 = lshr i32 %1, 2
@@ -344,13 +310,11 @@ define i64 @test_lshr__exact_is_safe(i32
 
 define i64 @test_lshr_exact__exact_is_unsafe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_lshr_exact__exact_is_unsafe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 63
-; CHECK-NEXT:    [[TMP2:%.*]] = lshr exact i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 15
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, 63
   %2 = lshr exact i32 %1, 2
@@ -380,13 +344,11 @@ define i64 @test_lshr__exact_is_unsafe(i
 
 define i64 @test_ashr_exact__exact_is_safe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_ashr_exact__exact_is_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2147483588
-; CHECK-NEXT:    [[TMP2:%.*]] = ashr exact i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = ashr i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -536870897
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, -2147483588
   %2 = ashr exact i32 %1, 2
@@ -399,13 +361,11 @@ define i64 @test_ashr_exact__exact_is_sa
 
 define i64 @test_ashr__exact_is_safe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_ashr__exact_is_safe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2147483588
-; CHECK-NEXT:    [[TMP2:%.*]] = ashr exact i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = ashr i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -536870897
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, -2147483588
   %2 = ashr i32 %1, 2
@@ -418,13 +378,11 @@ define i64 @test_ashr__exact_is_safe(i32
 
 define i64 @test_ashr_exact__exact_is_unsafe(i32 %x, i64 %y) {
 ; CHECK-LABEL: @test_ashr_exact__exact_is_unsafe(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2147483585
-; CHECK-NEXT:    [[TMP2:%.*]] = ashr exact i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[NARROW:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP4:%.*]] = zext i32 [[NARROW]] to i64
-; CHECK-NEXT:    [[TMP5:%.*]] = ashr i64 [[Y:%.*]], [[TMP4]]
-; CHECK-NEXT:    ret i64 [[TMP5]]
+; CHECK-NEXT:    [[TMP1:%.*]] = ashr i32 [[X:%.*]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -536870897
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = ashr i64 [[Y:%.*]], [[TMP3]]
+; CHECK-NEXT:    ret i64 [[TMP4]]
 ;
   %1 = and i32 %x, -2147483585
   %2 = ashr exact i32 %1, 2
@@ -455,10 +413,8 @@ define i64 @test_ashr__exact_is_unsafe(i
 define i32 @test_add_nuw_nsw__all_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_add_nuw_nsw__all_are_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 1073741823
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 3
 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[AND]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 4, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %and = and i32 %x, 1073741823
   %cmp = icmp eq i32 %and, 3
@@ -470,10 +426,8 @@ define i32 @test_add_nuw_nsw__all_are_sa
 define i32 @test_add_nuw__all_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_add_nuw__all_are_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 1073741823
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 3
 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[AND]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 4, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %and = and i32 %x, 1073741823
   %cmp = icmp eq i32 %and, 3
@@ -485,10 +439,8 @@ define i32 @test_add_nuw__all_are_safe(i
 define i32 @test_add_nsw__all_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_add_nsw__all_are_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 1073741823
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 3
 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[AND]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 4, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %and = and i32 %x, 1073741823
   %cmp = icmp eq i32 %and, 3
@@ -500,10 +452,8 @@ define i32 @test_add_nsw__all_are_safe(i
 define i32 @test_add__all_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_add__all_are_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 1073741823
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 3
 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[AND]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 4, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %and = and i32 %x, 1073741823
   %cmp = icmp eq i32 %and, 3
@@ -515,10 +465,8 @@ define i32 @test_add__all_are_safe(i32 %
 define i32 @test_add_nuw_nsw__nuw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_add_nuw_nsw__nuw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 2147483647
-; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[AND]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -2147483648, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[AND]], 1
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %and = and i32 %x, 2147483647
   %cmp = icmp eq i32 %and, 2147483647
@@ -530,10 +478,8 @@ define i32 @test_add_nuw_nsw__nuw_is_saf
 define i32 @test_add_nuw__nuw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_add_nuw__nuw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 2147483647
 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[AND]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -2147483648, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %and = and i32 %x, 2147483647
   %cmp = icmp eq i32 %and, 2147483647
@@ -545,10 +491,8 @@ define i32 @test_add_nuw__nuw_is_safe(i3
 define i32 @test_add_nsw__nuw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_add_nsw__nuw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 2147483647
-; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[AND]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -2147483648, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[AND]], 1
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %and = and i32 %x, 2147483647
   %cmp = icmp eq i32 %and, 2147483647
@@ -560,10 +504,8 @@ define i32 @test_add_nsw__nuw_is_safe(i3
 define i32 @test_add__nuw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_add__nuw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 2147483647
 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[AND]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -2147483648, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %and = and i32 %x, 2147483647
   %cmp = icmp eq i32 %and, 2147483647
@@ -575,10 +517,8 @@ define i32 @test_add__nuw_is_safe(i32 %x
 define i32 @test_add_nuw_nsw__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_add_nuw_nsw__nsw_is_safe(
 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -1
-; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[OR]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 0, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[OR]], 1
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %or = or i32 %x, -2147483648
   %cmp = icmp eq i32 %or, -1
@@ -590,10 +530,8 @@ define i32 @test_add_nuw_nsw__nsw_is_saf
 define i32 @test_add_nuw__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_add_nuw__nsw_is_safe(
 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -1
-; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[OR]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 0, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[OR]], 1
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %or = or i32 %x, -2147483648
   %cmp = icmp eq i32 %or, -1
@@ -605,10 +543,8 @@ define i32 @test_add_nuw__nsw_is_safe(i3
 define i32 @test_add_nsw__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_add_nsw__nsw_is_safe(
 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -1
 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[OR]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 0, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %or = or i32 %x, -2147483648
   %cmp = icmp eq i32 %or, -1
@@ -620,10 +556,8 @@ define i32 @test_add_nsw__nsw_is_safe(i3
 define i32 @test_add__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_add__nsw_is_safe(
 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -1
 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[OR]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 0, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %or = or i32 %x, -2147483648
   %cmp = icmp eq i32 %or, -1
@@ -634,10 +568,8 @@ define i32 @test_add__nsw_is_safe(i32 %x
 
 define i32 @test_add_nuw_nsw__none_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_add_nuw_nsw__none_are_safe(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
-; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[X]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 4, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X:%.*]], 1
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %cmp = icmp eq i32 %x, 3
   %add = add nuw nsw i32 %x, 1
@@ -647,10 +579,8 @@ define i32 @test_add_nuw_nsw__none_are_s
 
 define i32 @test_add_nuw__none_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_add_nuw__none_are_safe(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
-; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[X]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 4, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X:%.*]], 1
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %cmp = icmp eq i32 %x, 3
   %add = add nuw i32 %x, 1
@@ -660,10 +590,8 @@ define i32 @test_add_nuw__none_are_safe(
 
 define i32 @test_add_nsw__none_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_add_nsw__none_are_safe(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 3
-; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 4, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X:%.*]], 1
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %cmp = icmp eq i32 %x, 3
   %add = add nsw i32 %x, 1
@@ -685,10 +613,8 @@ define i32 @test_add__none_are_safe(i32
 define i32 @test_sub_nuw_nsw__all_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_sub_nuw_nsw__all_are_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 6
 ; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -254, [[AND]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -260, i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[SUB]]
 ;
   %and = and i32 %x, 255
   %cmp = icmp eq i32 %and, 6
@@ -700,10 +626,8 @@ define i32 @test_sub_nuw_nsw__all_are_sa
 define i32 @test_sub_nuw__all_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_sub_nuw__all_are_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 6
 ; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -254, [[AND]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -260, i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[SUB]]
 ;
   %and = and i32 %x, 255
   %cmp = icmp eq i32 %and, 6
@@ -715,10 +639,8 @@ define i32 @test_sub_nuw__all_are_safe(i
 define i32 @test_sub_nsw__all_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_sub_nsw__all_are_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 6
 ; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -254, [[AND]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -260, i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[SUB]]
 ;
   %and = and i32 %x, 255
   %cmp = icmp eq i32 %and, 6
@@ -730,10 +652,8 @@ define i32 @test_sub_nsw__all_are_safe(i
 define i32 @test_sub__all_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_sub__all_are_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 6
 ; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -254, [[AND]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -260, i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[SUB]]
 ;
   %and = and i32 %x, 255
   %cmp = icmp eq i32 %and, 6
@@ -745,10 +665,8 @@ define i32 @test_sub__all_are_safe(i32 %
 define i32 @test_sub_nuw_nsw__nuw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_sub_nuw_nsw__nuw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 1073741824
-; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -2147483648, [[AND]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 1073741824, i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[SUB:%.*]] = sub nuw i32 -2147483648, [[AND]]
+; CHECK-NEXT:    ret i32 [[SUB]]
 ;
   %and = and i32 %x, 2147483647
   %cmp = icmp eq i32 %and, 1073741824
@@ -760,10 +678,8 @@ define i32 @test_sub_nuw_nsw__nuw_is_saf
 define i32 @test_sub_nuw__nuw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_sub_nuw__nuw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 1073741824
 ; CHECK-NEXT:    [[SUB:%.*]] = sub nuw i32 -2147483648, [[AND]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 1073741824, i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[SUB]]
 ;
   %and = and i32 %x, 2147483647
   %cmp = icmp eq i32 %and, 1073741824
@@ -775,10 +691,8 @@ define i32 @test_sub_nuw__nuw_is_safe(i3
 define i32 @test_sub_nsw__nuw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_sub_nsw__nuw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 1073741824
-; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -2147483648, [[AND]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 1073741824, i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[SUB:%.*]] = sub nuw i32 -2147483648, [[AND]]
+; CHECK-NEXT:    ret i32 [[SUB]]
 ;
   %and = and i32 %x, 2147483647
   %cmp = icmp eq i32 %and, 1073741824
@@ -790,10 +704,8 @@ define i32 @test_sub_nsw__nuw_is_safe(i3
 define i32 @test_sub__nuw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_sub__nuw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483647
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 1073741824
 ; CHECK-NEXT:    [[SUB:%.*]] = sub nuw i32 -2147483648, [[AND]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 1073741824, i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[SUB]]
 ;
   %and = and i32 %x, 2147483647
   %cmp = icmp eq i32 %and, 1073741824
@@ -805,10 +717,8 @@ define i32 @test_sub__nuw_is_safe(i32 %x
 define i32 @test_sub_nuw_nsw__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_sub_nuw_nsw__nsw_is_safe(
 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -2147483647
-; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -2147483648, [[OR]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1, i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 -2147483648, [[OR]]
+; CHECK-NEXT:    ret i32 [[SUB]]
 ;
   %or = or i32 %x, -2147483648
   %cmp = icmp eq i32 %or, -2147483647
@@ -820,10 +730,8 @@ define i32 @test_sub_nuw_nsw__nsw_is_saf
 define i32 @test_sub_nuw__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_sub_nuw__nsw_is_safe(
 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -2147483647
-; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -2147483648, [[OR]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1, i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 -2147483648, [[OR]]
+; CHECK-NEXT:    ret i32 [[SUB]]
 ;
   %or = or i32 %x, -2147483648
   %cmp = icmp eq i32 %or, -2147483647
@@ -835,10 +743,8 @@ define i32 @test_sub_nuw__nsw_is_safe(i3
 define i32 @test_sub_nsw__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_sub_nsw__nsw_is_safe(
 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -2147483647
 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 -2147483648, [[OR]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1, i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[SUB]]
 ;
   %or = or i32 %x, -2147483648
   %cmp = icmp eq i32 %or, -2147483647
@@ -850,10 +756,8 @@ define i32 @test_sub_nsw__nsw_is_safe(i3
 define i32 @test_sub__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_sub__nsw_is_safe(
 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[X:%.*]], -2147483648
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[OR]], -2147483647
 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 -2147483648, [[OR]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1, i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[SUB]]
 ;
   %or = or i32 %x, -2147483648
   %cmp = icmp eq i32 %or, -2147483647
@@ -864,10 +768,8 @@ define i32 @test_sub__nsw_is_safe(i32 %x
 
 define i32 @test_sub_nuw_nsw__none_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_sub_nuw_nsw__none_are_safe(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 1
-; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 -2147483648, [[X]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 2147483647, i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[SUB:%.*]] = sub i32 -2147483648, [[X:%.*]]
+; CHECK-NEXT:    ret i32 [[SUB]]
 ;
   %cmp = icmp eq i32 %x, 1
   %sub = sub nuw nsw i32 -2147483648, %x
@@ -877,10 +779,8 @@ define i32 @test_sub_nuw_nsw__none_are_s
 
 define i32 @test_sub_nuw__none_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_sub_nuw__none_are_safe(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 1
-; CHECK-NEXT:    [[SUB:%.*]] = sub nuw i32 -2147483648, [[X]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 2147483647, i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[SUB:%.*]] = sub i32 -2147483648, [[X:%.*]]
+; CHECK-NEXT:    ret i32 [[SUB]]
 ;
   %cmp = icmp eq i32 %x, 1
   %sub = sub nuw i32 -2147483648, %x
@@ -890,10 +790,8 @@ define i32 @test_sub_nuw__none_are_safe(
 
 define i32 @test_sub_nsw__none_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_sub_nsw__none_are_safe(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 1
-; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 -2147483648, [[X]]
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 2147483647, i32 [[SUB]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[SUB:%.*]] = sub i32 -2147483648, [[X:%.*]]
+; CHECK-NEXT:    ret i32 [[SUB]]
 ;
   %cmp = icmp eq i32 %x, 1
   %sub = sub nsw i32 -2147483648, %x
@@ -915,10 +813,8 @@ define i32 @test_sub__none_are_safe(i32
 define i32 @test_mul_nuw_nsw__all_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_mul_nuw_nsw__all_are_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 17
 ; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 153, i32 [[MUL]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %and = and i32 %x, 255
   %cmp = icmp eq i32 %and, 17
@@ -930,10 +826,8 @@ define i32 @test_mul_nuw_nsw__all_are_sa
 define i32 @test_mul_nuw__all_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_mul_nuw__all_are_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 17
 ; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 153, i32 [[MUL]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %and = and i32 %x, 255
   %cmp = icmp eq i32 %and, 17
@@ -945,10 +839,8 @@ define i32 @test_mul_nuw__all_are_safe(i
 define i32 @test_mul_nsw__all_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_mul_nsw__all_are_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 17
 ; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 153, i32 [[MUL]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %and = and i32 %x, 255
   %cmp = icmp eq i32 %and, 17
@@ -960,10 +852,8 @@ define i32 @test_mul_nsw__all_are_safe(i
 define i32 @test_mul__all_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_mul__all_are_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 255
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 17
 ; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 153, i32 [[MUL]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %and = and i32 %x, 255
   %cmp = icmp eq i32 %and, 17
@@ -975,10 +865,8 @@ define i32 @test_mul__all_are_safe(i32 %
 define i32 @test_mul_nuw_nsw__nuw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_mul_nuw_nsw__nuw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 268435457
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 268435456
-; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1879048192, i32 [[MUL]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[AND]], 9
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %and = and i32 %x, 268435457
   %cmp = icmp eq i32 %and, 268435456
@@ -990,10 +878,8 @@ define i32 @test_mul_nuw_nsw__nuw_is_saf
 define i32 @test_mul_nuw__nuw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_mul_nuw__nuw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 268435457
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 268435456
 ; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[AND]], 9
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1879048192, i32 [[MUL]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %and = and i32 %x, 268435457
   %cmp = icmp eq i32 %and, 268435456
@@ -1005,10 +891,8 @@ define i32 @test_mul_nuw__nuw_is_safe(i3
 define i32 @test_mul_nsw__nuw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_mul_nsw__nuw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 268435457
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 268435456
-; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1879048192, i32 [[MUL]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[AND]], 9
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %and = and i32 %x, 268435457
   %cmp = icmp eq i32 %and, 268435456
@@ -1020,10 +904,8 @@ define i32 @test_mul_nsw__nuw_is_safe(i3
 define i32 @test_mul__nuw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_mul__nuw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 268435457
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 268435456
 ; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[AND]], 9
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1879048192, i32 [[MUL]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %and = and i32 %x, 268435457
   %cmp = icmp eq i32 %and, 268435456
@@ -1035,10 +917,8 @@ define i32 @test_mul__nuw_is_safe(i32 %x
 define i32 @test_mul_nuw_nsw__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_mul_nuw_nsw__nsw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = or i32 [[X:%.*]], -83886080
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], -83886079
-; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -754974711, i32 [[MUL]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[AND]], 9
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %and = or i32 %x, -83886080
   %cmp = icmp eq i32 %and, -83886079
@@ -1050,10 +930,8 @@ define i32 @test_mul_nuw_nsw__nsw_is_saf
 define i32 @test_mul_nuw__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_mul_nuw__nsw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = or i32 [[X:%.*]], -83886080
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], -83886079
-; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[AND]], 9
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -754974711, i32 [[MUL]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[AND]], 9
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %and = or i32 %x, -83886080
   %cmp = icmp eq i32 %and, -83886079
@@ -1065,10 +943,8 @@ define i32 @test_mul_nuw__nsw_is_safe(i3
 define i32 @test_mul_nsw__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_mul_nsw__nsw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = or i32 [[X:%.*]], -83886080
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], -83886079
 ; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[AND]], 9
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -754974711, i32 [[MUL]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %and = or i32 %x, -83886080
   %cmp = icmp eq i32 %and, -83886079
@@ -1080,10 +956,8 @@ define i32 @test_mul_nsw__nsw_is_safe(i3
 define i32 @test_mul__nsw_is_safe(i32 %x) {
 ; CHECK-LABEL: @test_mul__nsw_is_safe(
 ; CHECK-NEXT:    [[AND:%.*]] = or i32 [[X:%.*]], -83886080
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], -83886079
 ; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[AND]], 9
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -754974711, i32 [[MUL]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %and = or i32 %x, -83886080
   %cmp = icmp eq i32 %and, -83886079
@@ -1094,10 +968,8 @@ define i32 @test_mul__nsw_is_safe(i32 %x
 
 define i32 @test_mul_nuw_nsw__none_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_mul_nuw_nsw__none_are_safe(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 805306368
-; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[X]], 9
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1342177280, i32 [[MUL]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[X:%.*]], 9
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %cmp = icmp eq i32 %x, 805306368
   %mul = mul nuw nsw i32 %x, 9
@@ -1107,10 +979,8 @@ define i32 @test_mul_nuw_nsw__none_are_s
 
 define i32 @test_mul_nuw__none_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_mul_nuw__none_are_safe(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 805306368
-; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[X]], 9
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1342177280, i32 [[MUL]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[X:%.*]], 9
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %cmp = icmp eq i32 %x, 805306368
   %mul = mul nuw i32 %x, 9
@@ -1120,10 +990,8 @@ define i32 @test_mul_nuw__none_are_safe(
 
 define i32 @test_mul_nsw__none_are_safe(i32 %x) {
 ; CHECK-LABEL: @test_mul_nsw__none_are_safe(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 805306368
-; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[X]], 9
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1342177280, i32 [[MUL]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[X:%.*]], 9
+; CHECK-NEXT:    ret i32 [[MUL]]
 ;
   %cmp = icmp eq i32 %x, 805306368
   %mul = mul nsw i32 %x, 9

Modified: llvm/trunk/test/Transforms/InstCombine/select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select.ll?rev=367695&r1=367694&r2=367695&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/select.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/select.ll Fri Aug  2 10:39:32 2019
@@ -1318,10 +1318,8 @@ define i32 @test_select_select1(i32 %a,
 
 define i32 @PR23757(i32 %x) {
 ; CHECK-LABEL: @PR23757(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 2147483647
-; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -2147483648, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X:%.*]], 1
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %cmp = icmp eq i32 %x, 2147483647
   %add = add nsw i32 %x, 1
@@ -1331,10 +1329,7 @@ define i32 @PR23757(i32 %x) {
 
 define i32 @PR23757_swapped(i32 %x) {
 ; CHECK-LABEL: @PR23757_swapped(
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 2147483647
-; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[ADD]], i32 -2147483648
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 -2147483648
 ;
   %cmp = icmp eq i32 %x, 2147483647
   %add = add nsw i32 %x, 1
@@ -1346,9 +1341,7 @@ define i32 @PR23757_ne(i32 %x, i1* %p) {
 ; CHECK-LABEL: @PR23757_ne(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 2147483647
 ; CHECK-NEXT:    store i1 [[CMP]], i1* [[P:%.*]], align 1
-; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -2147483648, i32 [[ADD]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    ret i32 -2147483648
 ;
   %cmp = icmp ne i32 %x, 2147483647
   store i1 %cmp, i1* %p ; thwart predicate canonicalization
@@ -1361,9 +1354,8 @@ define i32 @PR23757_ne_swapped(i32 %x, i
 ; CHECK-LABEL: @PR23757_ne_swapped(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 2147483647
 ; CHECK-NEXT:    store i1 [[CMP]], i1* [[P:%.*]], align 1
-; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[X]], 1
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[ADD]], i32 -2147483648
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 1
+; CHECK-NEXT:    ret i32 [[ADD]]
 ;
   %cmp = icmp ne i32 %x, 2147483647
   store i1 %cmp, i1* %p ; thwart predicate canonicalization




More information about the llvm-commits mailing list