[llvm-branch-commits] [llvm] fb063c9 - [InstCombine] Duplicate tests for logical and/or (NFC)

Nikita Popov via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Jan 12 12:55:41 PST 2021


Author: Nikita Popov
Date: 2021-01-12T21:50:41+01:00
New Revision: fb063c933f0062db7fee622f7a43a6a5e560672d

URL: https://github.com/llvm/llvm-project/commit/fb063c933f0062db7fee622f7a43a6a5e560672d
DIFF: https://github.com/llvm/llvm-project/commit/fb063c933f0062db7fee622f7a43a6a5e560672d.diff

LOG: [InstCombine] Duplicate tests for logical and/or (NFC)

This replicates existing and/or tests to also test variants using
select. This should help us get a more accurate view on which
optimizations we're missing if we disable the select -> and/or
fold.

Added: 
    

Modified: 
    llvm/test/Transforms/InstCombine/2006-12-15-Range-Test.ll
    llvm/test/Transforms/InstCombine/2007-03-13-CompareMerge.ll
    llvm/test/Transforms/InstCombine/2007-05-10-icmp-or.ll
    llvm/test/Transforms/InstCombine/2007-11-15-CompareMiscomp.ll
    llvm/test/Transforms/InstCombine/2008-01-13-AndCmpCmp.ll
    llvm/test/Transforms/InstCombine/2008-02-28-OrFCmpCrash.ll
    llvm/test/Transforms/InstCombine/2008-06-21-CompareMiscomp.ll
    llvm/test/Transforms/InstCombine/2008-08-05-And.ll
    llvm/test/Transforms/InstCombine/2012-02-28-ICmp.ll
    llvm/test/Transforms/InstCombine/2012-03-10-InstCombine.ll
    llvm/test/Transforms/InstCombine/and-fcmp.ll
    llvm/test/Transforms/InstCombine/and-or-icmp-min-max.ll
    llvm/test/Transforms/InstCombine/and-or-icmp-nullptr.ll
    llvm/test/Transforms/InstCombine/and-or-icmps.ll
    llvm/test/Transforms/InstCombine/and.ll
    llvm/test/Transforms/InstCombine/and2.ll
    llvm/test/Transforms/InstCombine/assume.ll
    llvm/test/Transforms/InstCombine/bit-checks.ll
    llvm/test/Transforms/InstCombine/canonicalize-clamp-with-select-of-constant-threshold-pattern.ll
    llvm/test/Transforms/InstCombine/demorgan.ll
    llvm/test/Transforms/InstCombine/dont-distribute-phi.ll
    llvm/test/Transforms/InstCombine/fold-bin-operand.ll
    llvm/test/Transforms/InstCombine/freeze.ll
    llvm/test/Transforms/InstCombine/icmp-custom-dl.ll
    llvm/test/Transforms/InstCombine/icmp-logical.ll
    llvm/test/Transforms/InstCombine/icmp.ll
    llvm/test/Transforms/InstCombine/ispow2.ll
    llvm/test/Transforms/InstCombine/logical-select-inseltpoison.ll
    llvm/test/Transforms/InstCombine/logical-select.ll
    llvm/test/Transforms/InstCombine/merge-icmp.ll
    llvm/test/Transforms/InstCombine/objsize-noverify.ll
    llvm/test/Transforms/InstCombine/onehot_merge.ll
    llvm/test/Transforms/InstCombine/or-fcmp.ll
    llvm/test/Transforms/InstCombine/or.ll
    llvm/test/Transforms/InstCombine/prevent-cmp-merge.ll
    llvm/test/Transforms/InstCombine/range-check.ll
    llvm/test/Transforms/InstCombine/result-of-add-of-negative-is-non-zero-and-no-underflow.ll
    llvm/test/Transforms/InstCombine/result-of-add-of-negative-or-zero-is-non-zero-and-no-underflow.ll
    llvm/test/Transforms/InstCombine/result-of-usub-is-non-zero-and-no-overflow.ll
    llvm/test/Transforms/InstCombine/select-crash-noverify.ll
    llvm/test/Transforms/InstCombine/select-ctlz-to-cttz.ll
    llvm/test/Transforms/InstCombine/select-imm-canon.ll
    llvm/test/Transforms/InstCombine/select.ll
    llvm/test/Transforms/InstCombine/set.ll
    llvm/test/Transforms/InstCombine/sign-test-and-or.ll
    llvm/test/Transforms/InstCombine/signed-truncation-check.ll
    llvm/test/Transforms/InstCombine/umul-sign-check.ll
    llvm/test/Transforms/InstCombine/usub-overflow-known-by-implied-cond.ll
    llvm/test/Transforms/InstCombine/widenable-conditions.ll
    llvm/test/Transforms/InstCombine/zext-or-icmp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/InstCombine/2006-12-15-Range-Test.ll b/llvm/test/Transforms/InstCombine/2006-12-15-Range-Test.ll
index 38f6523bec39..3d08ae5e4012 100644
--- a/llvm/test/Transforms/InstCombine/2006-12-15-Range-Test.ll
+++ b/llvm/test/Transforms/InstCombine/2006-12-15-Range-Test.ll
@@ -42,3 +42,40 @@ cond_true:              ; preds = %newFuncRoot
   br i1 %bothcond, label %bb27.exitStub, label %cond_next23.exitStub
 }
 
+define i1 @print_pgm_cond_true_logical(i32 %tmp12.reload, i32* %tmp16.out) {
+; CHECK-LABEL: @print_pgm_cond_true_logical(
+; CHECK-NEXT:  newFuncRoot:
+; CHECK-NEXT:    br label [[COND_TRUE:%.*]]
+; CHECK:       bb27.exitStub:
+; CHECK-NEXT:    store i32 [[TMP16:%.*]], i32* [[TMP16_OUT:%.*]], align 4
+; CHECK-NEXT:    ret i1 true
+; CHECK:       cond_next23.exitStub:
+; CHECK-NEXT:    store i32 [[TMP16]], i32* [[TMP16_OUT]], align 4
+; CHECK-NEXT:    ret i1 false
+; CHECK:       cond_true:
+; CHECK-NEXT:    [[TMP15:%.*]] = getelementptr [17 x i32], [17 x i32]* @r, i32 0, i32 [[TMP12_RELOAD:%.*]]
+; CHECK-NEXT:    [[TMP16]] = load i32, i32* [[TMP15]], align 4
+; CHECK-NEXT:    [[TMP16_OFF:%.*]] = add i32 [[TMP16]], 31
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[TMP16_OFF]], 62
+; CHECK-NEXT:    br i1 [[TMP0]], label [[BB27_EXITSTUB:%.*]], label [[COND_NEXT23_EXITSTUB:%.*]]
+;
+newFuncRoot:
+  br label %cond_true
+
+bb27.exitStub:          ; preds = %cond_true
+  store i32 %tmp16, i32* %tmp16.out
+  ret i1 true
+
+cond_next23.exitStub:           ; preds = %cond_true
+  store i32 %tmp16, i32* %tmp16.out
+  ret i1 false
+
+cond_true:              ; preds = %newFuncRoot
+  %tmp15 = getelementptr [17 x i32], [17 x i32]* @r, i32 0, i32 %tmp12.reload         ; <i32*> [#uses=1]
+  %tmp16 = load i32, i32* %tmp15               ; <i32> [#uses=4]
+  %tmp18 = icmp slt i32 %tmp16, -31               ; <i1> [#uses=1]
+  %tmp21 = icmp sgt i32 %tmp16, 31                ; <i1> [#uses=1]
+  %bothcond = select i1 %tmp18, i1 true, i1 %tmp21                ; <i1> [#uses=1]
+  br i1 %bothcond, label %bb27.exitStub, label %cond_next23.exitStub
+}
+

diff  --git a/llvm/test/Transforms/InstCombine/2007-03-13-CompareMerge.ll b/llvm/test/Transforms/InstCombine/2007-03-13-CompareMerge.ll
index 6db886b25ede..7cedb1c5ced2 100644
--- a/llvm/test/Transforms/InstCombine/2007-03-13-CompareMerge.ll
+++ b/llvm/test/Transforms/InstCombine/2007-03-13-CompareMerge.ll
@@ -13,3 +13,14 @@ define i1 @test(i32 %c.3.i, i32 %d.292.2.i) {
   %sel_tmp80 = or i1 %tmp266.i, %tmp276.i
   ret i1 %sel_tmp80
 }
+
+define i1 @test_logical(i32 %c.3.i, i32 %d.292.2.i) {
+; CHECK-LABEL: @test_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sle i32 [[C_3_I:%.*]], [[D_292_2_I:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %tmp266.i = icmp slt i32 %c.3.i, %d.292.2.i
+  %tmp276.i = icmp eq i32 %c.3.i, %d.292.2.i
+  %sel_tmp80 = select i1 %tmp266.i, i1 true, i1 %tmp276.i
+  ret i1 %sel_tmp80
+}

diff  --git a/llvm/test/Transforms/InstCombine/2007-05-10-icmp-or.ll b/llvm/test/Transforms/InstCombine/2007-05-10-icmp-or.ll
index fb9b9a6cb5af..f019507082b3 100644
--- a/llvm/test/Transforms/InstCombine/2007-05-10-icmp-or.ll
+++ b/llvm/test/Transforms/InstCombine/2007-05-10-icmp-or.ll
@@ -12,3 +12,14 @@ define i1 @test(i32 %tmp9) {
   ret i1 %bothcond
 }
 
+define i1 @test_logical(i32 %tmp9) {
+; CHECK-LABEL: @test_logical(
+; CHECK-NEXT:    [[TMP20:%.*]] = icmp ugt i32 [[TMP9:%.*]], 255
+; CHECK-NEXT:    ret i1 [[TMP20]]
+;
+  %tmp20 = icmp ugt i32 %tmp9, 255                ; <i1> [#uses=1]
+  %tmp11.not = icmp sgt i32 %tmp9, 255            ; <i1> [#uses=1]
+  %bothcond = select i1 %tmp20, i1 true, i1 %tmp11.not            ; <i1> [#uses=1]
+  ret i1 %bothcond
+}
+

diff  --git a/llvm/test/Transforms/InstCombine/2007-11-15-CompareMiscomp.ll b/llvm/test/Transforms/InstCombine/2007-11-15-CompareMiscomp.ll
index f872b6a98e09..8efa821d7de0 100644
--- a/llvm/test/Transforms/InstCombine/2007-11-15-CompareMiscomp.ll
+++ b/llvm/test/Transforms/InstCombine/2007-11-15-CompareMiscomp.ll
@@ -14,3 +14,14 @@ define i1 @test(i32 %In) {
   ret i1 %V
 }
 
+define i1 @test_logical(i32 %In) {
+; CHECK-LABEL: @test_logical(
+; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 [[IN:%.*]], 1
+; CHECK-NEXT:    ret i1 [[C2]]
+;
+  %c1 = icmp sgt i32 %In, -1
+  %c2 = icmp eq i32 %In, 1
+  %V = select i1 %c1, i1 %c2, i1 false
+  ret i1 %V
+}
+

diff  --git a/llvm/test/Transforms/InstCombine/2008-01-13-AndCmpCmp.ll b/llvm/test/Transforms/InstCombine/2008-01-13-AndCmpCmp.ll
index eb3329b4dd02..6dde4402e1fb 100644
--- a/llvm/test/Transforms/InstCombine/2008-01-13-AndCmpCmp.ll
+++ b/llvm/test/Transforms/InstCombine/2008-01-13-AndCmpCmp.ll
@@ -15,3 +15,16 @@ define i1 @test(i32 %c84.17) {
   %tmp2703 = and i1 %tmp2696, %tmp2699		; <i1> [#uses=1]
   ret i1 %tmp2703
 }
+
+define i1 @test_logical(i32 %c84.17) {
+; CHECK-LABEL: @test_logical(
+; CHECK-NEXT:    [[TMP2696:%.*]] = icmp ne i32 [[C84_17:%.*]], 34
+; CHECK-NEXT:    [[TMP2699:%.*]] = icmp sgt i32 [[C84_17]], -1
+; CHECK-NEXT:    [[TMP2703:%.*]] = and i1 [[TMP2696]], [[TMP2699]]
+; CHECK-NEXT:    ret i1 [[TMP2703]]
+;
+  %tmp2696 = icmp ne i32 %c84.17, 34
+  %tmp2699 = icmp sgt i32 %c84.17, -1
+  %tmp2703 = select i1 %tmp2696, i1 %tmp2699, i1 false
+  ret i1 %tmp2703
+}

diff  --git a/llvm/test/Transforms/InstCombine/2008-02-28-OrFCmpCrash.ll b/llvm/test/Transforms/InstCombine/2008-02-28-OrFCmpCrash.ll
index 7b08a7b3a025..50657d744da1 100644
--- a/llvm/test/Transforms/InstCombine/2008-02-28-OrFCmpCrash.ll
+++ b/llvm/test/Transforms/InstCombine/2008-02-28-OrFCmpCrash.ll
@@ -27,3 +27,28 @@ bb74:		; preds = %entry
 bb80:		; preds = %entry
   ret float 0.000000e+00
 }
+
+define float @test_logical(float %x, x86_fp80 %y) nounwind readonly  {
+; CHECK-LABEL: @test_logical(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP67:%.*]] = fcmp uno x86_fp80 [[Y:%.*]], 0xK00000000000000000000
+; CHECK-NEXT:    [[TMP71:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[BOTHCOND:%.*]] = or i1 [[TMP67]], [[TMP71]]
+; CHECK-NEXT:    br i1 [[BOTHCOND]], label [[BB74:%.*]], label [[BB80:%.*]]
+; CHECK:       bb74:
+; CHECK-NEXT:    ret float 0.000000e+00
+; CHECK:       bb80:
+; CHECK-NEXT:    ret float 0.000000e+00
+;
+entry:
+  %tmp67 = fcmp uno x86_fp80 %y, 0xK00000000000000000000		; <i1> [#uses=1]
+  %tmp71 = fcmp uno float %x, 0.000000e+00		; <i1> [#uses=1]
+  %bothcond = select i1 %tmp67, i1 true, i1 %tmp71		; <i1> [#uses=1]
+  br i1 %bothcond, label %bb74, label %bb80
+
+bb74:		; preds = %entry
+  ret float 0.000000e+00
+
+bb80:		; preds = %entry
+  ret float 0.000000e+00
+}

diff  --git a/llvm/test/Transforms/InstCombine/2008-06-21-CompareMiscomp.ll b/llvm/test/Transforms/InstCombine/2008-06-21-CompareMiscomp.ll
index 11226bcf4185..2b0f364ee375 100644
--- a/llvm/test/Transforms/InstCombine/2008-06-21-CompareMiscomp.ll
+++ b/llvm/test/Transforms/InstCombine/2008-06-21-CompareMiscomp.ll
@@ -15,3 +15,14 @@ define i1 @test(i32 %In) {
   ret i1 %V
 }
 
+define i1 @test_logical(i32 %In) {
+; CHECK-LABEL: @test_logical(
+; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 [[IN:%.*]], 15
+; CHECK-NEXT:    ret i1 [[C2]]
+;
+  %c1 = icmp ugt i32 %In, 13
+  %c2 = icmp eq i32 %In, 15
+  %V = select i1 %c1, i1 %c2, i1 false
+  ret i1 %V
+}
+

diff  --git a/llvm/test/Transforms/InstCombine/2008-08-05-And.ll b/llvm/test/Transforms/InstCombine/2008-08-05-And.ll
index 9efc35fb2d20..bec055a2ee7c 100644
--- a/llvm/test/Transforms/InstCombine/2008-08-05-And.ll
+++ b/llvm/test/Transforms/InstCombine/2008-08-05-And.ll
@@ -38,3 +38,40 @@ okay:
 incompatible:
   ret void
 }
+
+define void @f_logical(i8* %x) nounwind  {
+; CHECK-LABEL: @f_logical(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[BB:%.*]]
+; CHECK:       bb:
+; CHECK-NEXT:    [[L1:%.*]] = load i8, i8* [[X:%.*]], align 1
+; CHECK-NEXT:    [[S1:%.*]] = add i8 [[L1]], -6
+; CHECK-NEXT:    [[C1:%.*]] = icmp ugt i8 [[S1]], 2
+; CHECK-NEXT:    [[S2:%.*]] = add i8 [[L1]], -10
+; CHECK-NEXT:    [[C2:%.*]] = icmp ugt i8 [[S2]], 2
+; CHECK-NEXT:    [[A1:%.*]] = and i1 [[C1]], [[C2]]
+; CHECK-NEXT:    br i1 [[A1]], label [[INCOMPATIBLE:%.*]], label [[OKAY:%.*]]
+; CHECK:       okay:
+; CHECK-NEXT:    ret void
+; CHECK:       incompatible:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %bb
+
+bb:
+  %g1 = getelementptr i8, i8* %x, i32 0
+  %l1 = load i8, i8* %g1, align 1
+  %s1 = sub i8 %l1, 6
+  %c1 = icmp ugt i8 %s1, 2
+  %s2 = sub i8 %l1, 10
+  %c2 = icmp ugt i8 %s2, 2
+  %a1 = select i1 %c1, i1 %c2, i1 false
+  br i1 %a1, label %incompatible, label %okay
+
+okay:
+  ret void
+
+incompatible:
+  ret void
+}

diff  --git a/llvm/test/Transforms/InstCombine/2012-02-28-ICmp.ll b/llvm/test/Transforms/InstCombine/2012-02-28-ICmp.ll
index 97956bc2e249..85792304c50d 100644
--- a/llvm/test/Transforms/InstCombine/2012-02-28-ICmp.ll
+++ b/llvm/test/Transforms/InstCombine/2012-02-28-ICmp.ll
@@ -20,3 +20,20 @@ define i1 @f1(i32 %x) {
   %e = and i1 %b, %d
   ret i1 %e
 }
+
+define i1 @f1_logical(i32 %x) {
+; CHECK-LABEL: @f1_logical(
+; CHECK-NEXT:    [[A:%.*]] = trunc i32 [[X:%.*]] to i8
+; CHECK-NEXT:    [[B:%.*]] = icmp ne i8 [[A]], 0
+; CHECK-NEXT:    [[C:%.*]] = and i32 [[X]], 16711680
+; CHECK-NEXT:    [[D:%.*]] = icmp ne i32 [[C]], 0
+; CHECK-NEXT:    [[E:%.*]] = and i1 [[B]], [[D]]
+; CHECK-NEXT:    ret i1 [[E]]
+;
+  %a = trunc i32 %x to i8
+  %b = icmp ne i8 %a, 0
+  %c = and i32 %x, 16711680
+  %d = icmp ne i32 %c, 0
+  %e = select i1 %b, i1 %d, i1 false
+  ret i1 %e
+}

diff  --git a/llvm/test/Transforms/InstCombine/2012-03-10-InstCombine.ll b/llvm/test/Transforms/InstCombine/2012-03-10-InstCombine.ll
index 8ef65a27c1f5..d180560bfbcc 100644
--- a/llvm/test/Transforms/InstCombine/2012-03-10-InstCombine.ll
+++ b/llvm/test/Transforms/InstCombine/2012-03-10-InstCombine.ll
@@ -50,3 +50,50 @@ return:                                           ; preds = %if.else, %if.then
   ret i32 %retval.0
 }
 
+define i32 @func_logical(i8* %c, i8* %f) nounwind uwtable readnone noinline ssp {
+; CHECK-LABEL: @func_logical(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[D:%.*]] = alloca i8, align 1
+; CHECK-NEXT:    store i8 0, i8* [[D]], align 1
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8* [[D]], [[C:%.*]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i8* [[D]], [[F:%.*]]
+; CHECK-NEXT:    [[NOT_CMP1:%.*]] = icmp uge i8* [[C]], [[F]]
+; CHECK-NEXT:    [[DOTCMP2:%.*]] = and i1 [[CMP2]], [[NOT_CMP1]]
+; CHECK-NEXT:    br label [[RETURN:%.*]]
+; CHECK:       if.else:
+; CHECK-NEXT:    [[CMP5:%.*]] = icmp uge i8* [[D]], [[F]]
+; CHECK-NEXT:    [[NOT_CMP3:%.*]] = icmp ule i8* [[C]], [[F]]
+; CHECK-NEXT:    [[DOTCMP5:%.*]] = and i1 [[CMP5]], [[NOT_CMP3]]
+; CHECK-NEXT:    br label [[RETURN]]
+; CHECK:       return:
+; CHECK-NEXT:    [[RETVAL_0_IN:%.*]] = phi i1 [ [[DOTCMP2]], [[IF_THEN]] ], [ [[DOTCMP5]], [[IF_ELSE]] ]
+; CHECK-NEXT:    [[RETVAL_0:%.*]] = zext i1 [[RETVAL_0_IN]] to i32
+; CHECK-NEXT:    ret i32 [[RETVAL_0]]
+;
+entry:
+  %d = alloca i8, align 1
+  store i8 0, i8* %d, align 1
+  %cmp = icmp ugt i8* %d, %c
+  br i1 %cmp, label %if.else, label %if.then
+
+if.then:                                          ; preds = %entry
+  %cmp2 = icmp ule i8* %d, %f
+  %not.cmp1 = icmp uge i8* %c, %f
+  %.cmp2 = select i1 %cmp2, i1 %not.cmp1, i1 false
+  %land.ext = zext i1 %.cmp2 to i32
+  br label %return
+
+if.else:                                          ; preds = %entry
+  %cmp5 = icmp uge i8* %d, %f
+  %not.cmp3 = icmp ule i8* %c, %f
+  %.cmp5 = select i1 %cmp5, i1 %not.cmp3, i1 false
+  %land.ext7 = zext i1 %.cmp5 to i32
+  br label %return
+
+return:                                           ; preds = %if.else, %if.then
+  %retval.0 = phi i32 [ %land.ext, %if.then ], [ %land.ext7, %if.else ]
+  ret i32 %retval.0
+}
+

diff  --git a/llvm/test/Transforms/InstCombine/and-fcmp.ll b/llvm/test/Transforms/InstCombine/and-fcmp.ll
index dd51c6548eea..18689c969bd0 100644
--- a/llvm/test/Transforms/InstCombine/and-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/and-fcmp.ll
@@ -12,6 +12,17 @@ define i1 @PR1738(double %x, double %y) {
   ret i1 %and
 }
 
+define i1 @PR1738_logical(double %x, double %y) {
+; CHECK-LABEL: @PR1738_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp1 = fcmp ord double %x, 0.0
+  %cmp2 = fcmp ord double %y, 0.0
+  %and = select i1 %cmp1, i1 %cmp2, i1 false
+  ret i1 %and
+}
+
 define <2 x i1> @PR1738_vec_undef(<2 x double> %x, <2 x double> %y) {
 ; CHECK-LABEL: @PR1738_vec_undef(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord <2 x double> [[X:%.*]], [[Y:%.*]]
@@ -36,6 +47,19 @@ define i1 @PR41069(i1 %z, float %c, float %d) {
   ret i1 %r
 }
 
+define i1 @PR41069_logical(i1 %z, float %c, float %d) {
+; CHECK-LABEL: @PR41069_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord float [[D:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[TMP1]], [[Z:%.*]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %ord1 = fcmp arcp ord float %c, 0.0
+  %and = select i1 %ord1, i1 %z, i1 false
+  %ord2 = fcmp afn ord float %d, 0.0
+  %r = select i1 %and, i1 %ord2, i1 false
+  ret i1 %r
+}
+
 define i1 @PR41069_commute(i1 %z, float %c, float %d) {
 ; CHECK-LABEL: @PR41069_commute(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ninf ord float [[D:%.*]], [[C:%.*]]
@@ -49,6 +73,19 @@ define i1 @PR41069_commute(i1 %z, float %c, float %d) {
   ret i1 %r
 }
 
+define i1 @PR41069_commute_logical(i1 %z, float %c, float %d) {
+; CHECK-LABEL: @PR41069_commute_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ninf ord float [[D:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[TMP1]], [[Z:%.*]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %ord1 = fcmp ninf ord float %c, 0.0
+  %and = select i1 %ord1, i1 %z, i1 false
+  %ord2 = fcmp ninf reassoc ord float %d, 0.0
+  %r = select i1 %ord2, i1 %and, i1 false
+  ret i1 %r
+}
+
 ; Commute 
diff erently and make sure vectors work.
 
 define <2 x i1> @PR41069_vec(<2 x double> %a, <2 x double> %b, <2 x double> %c, <2 x double> %d) {
@@ -94,6 +131,19 @@ define i1 @PR15737(float %a, double %b) {
   ret i1 %and
 }
 
+define i1 @PR15737_logical(float %a, double %b) {
+; CHECK-LABEL: @PR15737_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord float [[A:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord double [[B:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP]], [[CMP1]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %cmp = fcmp ord float %a, 0.000000e+00
+  %cmp1 = fcmp ord double %b, 0.000000e+00
+  %and = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %and
+}
+
 define <2 x i1> @t9(<2 x float> %a, <2 x double> %b) {
 ; CHECK-LABEL: @t9(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord <2 x float> [[A:%.*]], zeroinitializer
@@ -118,6 +168,17 @@ define i1 @fcmp_ord_nonzero(float %x, float %y) {
   ret i1 %and
 }
 
+define i1 @fcmp_ord_nonzero_logical(float %x, float %y) {
+; CHECK-LABEL: @fcmp_ord_nonzero_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp1 = fcmp ord float %x, 1.0
+  %cmp2 = fcmp ord float %y, 2.0
+  %and = select i1 %cmp1, i1 %cmp2, i1 false
+  ret i1 %and
+}
+
 define <3 x i1> @fcmp_ord_nonzero_vec(<3 x float> %x, <3 x float> %y) {
 ; CHECK-LABEL: @fcmp_ord_nonzero_vec(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord <3 x float> [[X:%.*]], [[Y:%.*]]
@@ -139,6 +200,16 @@ define i1 @auto_gen_0(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_0_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_0_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp false double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_1(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_1(
 ; CHECK-NEXT:    ret i1 false
@@ -149,6 +220,16 @@ define i1 @auto_gen_1(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_1_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_1_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp oeq double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_2(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_2(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
@@ -160,6 +241,17 @@ define i1 @auto_gen_2(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_2_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_2_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp oeq double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_3(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_3(
 ; CHECK-NEXT:    ret i1 false
@@ -170,6 +262,16 @@ define i1 @auto_gen_3(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_3_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_3_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ogt double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_4(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_4(
 ; CHECK-NEXT:    ret i1 false
@@ -180,6 +282,16 @@ define i1 @auto_gen_4(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_4_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_4_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ogt double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_5(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_5(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -191,6 +303,17 @@ define i1 @auto_gen_5(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_5_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_5_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ogt double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_6(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_6(
 ; CHECK-NEXT:    ret i1 false
@@ -201,6 +324,16 @@ define i1 @auto_gen_6(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_6_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_6_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp oge double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_7(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_7(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
@@ -212,6 +345,17 @@ define i1 @auto_gen_7(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_7_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_7_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp oge double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_8(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_8(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -223,6 +367,17 @@ define i1 @auto_gen_8(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_8_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_8_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp oge double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_9(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_9(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
@@ -234,6 +389,17 @@ define i1 @auto_gen_9(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_9_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_9_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp oge double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_10(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_10(
 ; CHECK-NEXT:    ret i1 false
@@ -244,6 +410,16 @@ define i1 @auto_gen_10(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_10_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_10_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp olt double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_11(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_11(
 ; CHECK-NEXT:    ret i1 false
@@ -254,6 +430,16 @@ define i1 @auto_gen_11(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_11_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_11_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp olt double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_12(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_12(
 ; CHECK-NEXT:    ret i1 false
@@ -264,6 +450,16 @@ define i1 @auto_gen_12(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_12_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_12_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp olt double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_13(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_13(
 ; CHECK-NEXT:    ret i1 false
@@ -274,6 +470,16 @@ define i1 @auto_gen_13(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_13_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_13_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp olt double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_14(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_14(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -285,6 +491,17 @@ define i1 @auto_gen_14(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_14_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_14_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp olt double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_15(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_15(
 ; CHECK-NEXT:    ret i1 false
@@ -295,6 +512,16 @@ define i1 @auto_gen_15(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_15_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_15_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ole double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_16(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_16(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
@@ -306,6 +533,17 @@ define i1 @auto_gen_16(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_16_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_16_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ole double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_17(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_17(
 ; CHECK-NEXT:    ret i1 false
@@ -316,6 +554,16 @@ define i1 @auto_gen_17(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_17_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_17_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ole double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_18(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_18(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
@@ -327,6 +575,17 @@ define i1 @auto_gen_18(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_18_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_18_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ole double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_19(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_19(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -338,6 +597,17 @@ define i1 @auto_gen_19(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_19_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_19_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ole double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_20(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_20(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
@@ -349,6 +619,17 @@ define i1 @auto_gen_20(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_20_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_20_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ole double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_21(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_21(
 ; CHECK-NEXT:    ret i1 false
@@ -359,6 +640,16 @@ define i1 @auto_gen_21(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_21_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_21_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp one double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_22(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_22(
 ; CHECK-NEXT:    ret i1 false
@@ -369,6 +660,16 @@ define i1 @auto_gen_22(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_22_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_22_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp one double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_23(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_23(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -380,6 +681,17 @@ define i1 @auto_gen_23(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_23_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_23_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp one double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_24(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_24(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -391,6 +703,17 @@ define i1 @auto_gen_24(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_24_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_24_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp one double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_25(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_25(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -402,6 +725,17 @@ define i1 @auto_gen_25(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_25_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_25_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp one double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_26(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_26(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -413,6 +747,17 @@ define i1 @auto_gen_26(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_26_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_26_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp one double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_27(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_27(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
@@ -424,6 +769,17 @@ define i1 @auto_gen_27(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_27_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_27_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp one double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_28(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_28(
 ; CHECK-NEXT:    ret i1 false
@@ -434,7 +790,17 @@ define i1 @auto_gen_28(double %a, double %b) {
   ret i1 %retval
 }
 
-define i1 @auto_gen_29(double %a, double %b) {
+define i1 @auto_gen_28_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_28_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
+define i1 @auto_gen_29(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_29(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    ret i1 [[TMP1]]
@@ -445,6 +811,17 @@ define i1 @auto_gen_29(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_29_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_29_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_30(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_30(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -456,6 +833,17 @@ define i1 @auto_gen_30(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_30_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_30_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_31(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_31(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
@@ -467,6 +855,17 @@ define i1 @auto_gen_31(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_31_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_31_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_32(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_32(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -478,6 +877,17 @@ define i1 @auto_gen_32(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_32_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_32_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_33(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_33(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
@@ -489,6 +899,17 @@ define i1 @auto_gen_33(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_33_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_33_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_34(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_34(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
@@ -500,6 +921,17 @@ define i1 @auto_gen_34(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_34_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_34_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_35(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_35(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
@@ -511,6 +943,17 @@ define i1 @auto_gen_35(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_35_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_35_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_36(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_36(
 ; CHECK-NEXT:    ret i1 false
@@ -521,6 +964,16 @@ define i1 @auto_gen_36(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_36_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_36_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_37(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_37(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
@@ -532,6 +985,17 @@ define i1 @auto_gen_37(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_37_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_37_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_38(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_38(
 ; CHECK-NEXT:    ret i1 false
@@ -542,6 +1006,16 @@ define i1 @auto_gen_38(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_38_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_38_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_39(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_39(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
@@ -553,6 +1027,17 @@ define i1 @auto_gen_39(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_39_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_39_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_40(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_40(
 ; CHECK-NEXT:    ret i1 false
@@ -563,6 +1048,16 @@ define i1 @auto_gen_40(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_40_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_40_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_41(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_41(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
@@ -574,6 +1069,17 @@ define i1 @auto_gen_41(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_41_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_41_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_42(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_42(
 ; CHECK-NEXT:    ret i1 false
@@ -584,6 +1090,16 @@ define i1 @auto_gen_42(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_42_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_42_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_43(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_43(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
@@ -595,6 +1111,17 @@ define i1 @auto_gen_43(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_43_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_43_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_44(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_44(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
@@ -606,6 +1133,17 @@ define i1 @auto_gen_44(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_44_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_44_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_45(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_45(
 ; CHECK-NEXT:    ret i1 false
@@ -616,6 +1154,16 @@ define i1 @auto_gen_45(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_45_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_45_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_46(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_46(
 ; CHECK-NEXT:    ret i1 false
@@ -626,6 +1174,16 @@ define i1 @auto_gen_46(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_46_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_46_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_47(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_47(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -637,6 +1195,17 @@ define i1 @auto_gen_47(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_47_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_47_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_48(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_48(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -648,6 +1217,17 @@ define i1 @auto_gen_48(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_48_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_48_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_49(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_49(
 ; CHECK-NEXT:    ret i1 false
@@ -658,6 +1238,16 @@ define i1 @auto_gen_49(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_49_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_49_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_50(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_50(
 ; CHECK-NEXT:    ret i1 false
@@ -668,6 +1258,16 @@ define i1 @auto_gen_50(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_50_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_50_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_51(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_51(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -679,6 +1279,17 @@ define i1 @auto_gen_51(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_51_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_51_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_52(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_52(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -690,6 +1301,17 @@ define i1 @auto_gen_52(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_52_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_52_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_53(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_53(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -701,6 +1323,17 @@ define i1 @auto_gen_53(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_53_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_53_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_54(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_54(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
@@ -712,6 +1345,17 @@ define i1 @auto_gen_54(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_54_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_54_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp ugt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_55(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_55(
 ; CHECK-NEXT:    ret i1 false
@@ -722,6 +1366,16 @@ define i1 @auto_gen_55(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_55_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_55_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_56(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_56(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
@@ -733,6 +1387,17 @@ define i1 @auto_gen_56(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_56_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_56_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_57(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_57(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -744,6 +1409,17 @@ define i1 @auto_gen_57(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_57_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_57_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_58(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_58(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
@@ -755,6 +1431,17 @@ define i1 @auto_gen_58(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_58_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_58_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_59(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_59(
 ; CHECK-NEXT:    ret i1 false
@@ -765,6 +1452,16 @@ define i1 @auto_gen_59(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_59_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_59_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_60(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_60(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
@@ -776,6 +1473,17 @@ define i1 @auto_gen_60(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_60_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_60_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_61(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_61(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -787,8 +1495,19 @@ define i1 @auto_gen_61(double %a, double %b) {
   ret i1 %retval
 }
 
-define i1 @auto_gen_62(double %a, double %b) {
-; CHECK-LABEL: @auto_gen_62(
+define i1 @auto_gen_61_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_61_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
+define i1 @auto_gen_62(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_62(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
@@ -798,6 +1517,17 @@ define i1 @auto_gen_62(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_62_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_62_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_63(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_63(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
@@ -809,6 +1539,17 @@ define i1 @auto_gen_63(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_63_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_63_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_64(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_64(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
@@ -820,6 +1561,17 @@ define i1 @auto_gen_64(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_64_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_64_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp ugt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_65(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_65(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -831,6 +1583,17 @@ define i1 @auto_gen_65(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_65_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_65_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp uge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_66(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_66(
 ; CHECK-NEXT:    ret i1 false
@@ -841,6 +1604,16 @@ define i1 @auto_gen_66(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_66_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_66_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_67(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_67(
 ; CHECK-NEXT:    ret i1 false
@@ -851,6 +1624,16 @@ define i1 @auto_gen_67(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_67_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_67_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_68(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_68(
 ; CHECK-NEXT:    ret i1 false
@@ -861,6 +1644,16 @@ define i1 @auto_gen_68(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_68_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_68_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_69(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_69(
 ; CHECK-NEXT:    ret i1 false
@@ -871,6 +1664,16 @@ define i1 @auto_gen_69(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_69_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_69_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_70(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_70(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -882,6 +1685,17 @@ define i1 @auto_gen_70(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_70_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_70_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_71(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_71(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -893,6 +1707,17 @@ define i1 @auto_gen_71(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_71_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_71_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_72(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_72(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -904,6 +1729,17 @@ define i1 @auto_gen_72(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_72_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_72_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_73(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_73(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -915,6 +1751,17 @@ define i1 @auto_gen_73(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_73_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_73_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_74(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_74(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -926,6 +1773,17 @@ define i1 @auto_gen_74(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_74_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_74_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_75(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_75(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -937,6 +1795,17 @@ define i1 @auto_gen_75(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_75_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_75_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp ugt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_76(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_76(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -948,6 +1817,17 @@ define i1 @auto_gen_76(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_76_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_76_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp uge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_77(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_77(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
@@ -959,6 +1839,17 @@ define i1 @auto_gen_77(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_77_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_77_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp ult double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_78(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_78(
 ; CHECK-NEXT:    ret i1 false
@@ -969,6 +1860,16 @@ define i1 @auto_gen_78(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_78_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_78_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_79(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_79(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
@@ -980,6 +1881,17 @@ define i1 @auto_gen_79(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_79_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_79_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_80(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_80(
 ; CHECK-NEXT:    ret i1 false
@@ -990,6 +1902,16 @@ define i1 @auto_gen_80(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_80_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_80_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_81(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_81(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
@@ -1001,6 +1923,17 @@ define i1 @auto_gen_81(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_81_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_81_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_82(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_82(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -1012,6 +1945,17 @@ define i1 @auto_gen_82(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_82_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_82_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_83(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_83(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
@@ -1023,6 +1967,17 @@ define i1 @auto_gen_83(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_83_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_83_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_84(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_84(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -1034,6 +1989,17 @@ define i1 @auto_gen_84(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_84_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_84_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_85(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_85(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
@@ -1045,6 +2011,17 @@ define i1 @auto_gen_85(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_85_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_85_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_86(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_86(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
@@ -1056,6 +2033,17 @@ define i1 @auto_gen_86(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_86_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_86_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_87(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_87(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -1067,6 +2055,17 @@ define i1 @auto_gen_87(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_87_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_87_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp ugt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_88(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_88(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
@@ -1078,6 +2077,17 @@ define i1 @auto_gen_88(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_88_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_88_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp uge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_89(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_89(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
@@ -1089,6 +2099,17 @@ define i1 @auto_gen_89(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_89_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_89_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp ult double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_90(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_90(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
@@ -1100,6 +2121,17 @@ define i1 @auto_gen_90(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_90_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_90_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp ule double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_91(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_91(
 ; CHECK-NEXT:    ret i1 false
@@ -1110,6 +2142,16 @@ define i1 @auto_gen_91(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_91_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_91_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_92(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_92(
 ; CHECK-NEXT:    ret i1 false
@@ -1120,6 +2162,16 @@ define i1 @auto_gen_92(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_92_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_92_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_93(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_93(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -1131,6 +2183,17 @@ define i1 @auto_gen_93(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_93_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_93_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_94(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_94(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -1142,6 +2205,17 @@ define i1 @auto_gen_94(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_94_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_94_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_95(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_95(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -1153,6 +2227,17 @@ define i1 @auto_gen_95(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_95_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_95_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_96(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_96(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -1164,6 +2249,17 @@ define i1 @auto_gen_96(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_96_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_96_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_97(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_97(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
@@ -1175,6 +2271,17 @@ define i1 @auto_gen_97(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_97_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_97_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_98(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_98(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
@@ -1186,6 +2293,17 @@ define i1 @auto_gen_98(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_98_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_98_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_99(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_99(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -1197,6 +2315,17 @@ define i1 @auto_gen_99(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_99_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_99_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_100(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_100(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
@@ -1208,6 +2337,17 @@ define i1 @auto_gen_100(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_100_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_100_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp ugt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_101(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_101(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
@@ -1219,6 +2359,17 @@ define i1 @auto_gen_101(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_101_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_101_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp uge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_102(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_102(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
@@ -1226,7 +2377,18 @@ define i1 @auto_gen_102(double %a, double %b) {
 ;
   %cmp = fcmp une double %a, %b
   %cmp1 = fcmp ult double %a, %b
-  %retval = and i1 %cmp, %cmp1
+  %retval = and i1 %cmp, %cmp1
+  ret i1 %retval
+}
+
+define i1 @auto_gen_102_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_102_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp ult double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
   ret i1 %retval
 }
 
@@ -1241,6 +2403,17 @@ define i1 @auto_gen_103(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_103_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_103_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp ule double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_104(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_104(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
@@ -1252,6 +2425,17 @@ define i1 @auto_gen_104(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_104_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_104_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp une double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_105(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_105(
 ; CHECK-NEXT:    ret i1 false
@@ -1262,6 +2446,16 @@ define i1 @auto_gen_105(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_105_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_105_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_106(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_106(
 ; CHECK-NEXT:    ret i1 false
@@ -1272,6 +2466,16 @@ define i1 @auto_gen_106(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_106_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_106_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_107(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_107(
 ; CHECK-NEXT:    ret i1 false
@@ -1282,6 +2486,16 @@ define i1 @auto_gen_107(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_107_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_107_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_108(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_108(
 ; CHECK-NEXT:    ret i1 false
@@ -1292,6 +2506,16 @@ define i1 @auto_gen_108(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_108_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_108_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_109(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_109(
 ; CHECK-NEXT:    ret i1 false
@@ -1302,6 +2526,16 @@ define i1 @auto_gen_109(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_109_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_109_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_110(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_110(
 ; CHECK-NEXT:    ret i1 false
@@ -1312,6 +2546,16 @@ define i1 @auto_gen_110(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_110_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_110_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_111(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_111(
 ; CHECK-NEXT:    ret i1 false
@@ -1322,6 +2566,16 @@ define i1 @auto_gen_111(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_111_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_111_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_112(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_112(
 ; CHECK-NEXT:    ret i1 false
@@ -1332,6 +2586,16 @@ define i1 @auto_gen_112(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_112_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_112_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_113(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_113(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -1343,6 +2607,17 @@ define i1 @auto_gen_113(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_113_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_113_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_114(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_114(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -1354,6 +2629,17 @@ define i1 @auto_gen_114(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_114_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_114_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp ugt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_115(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_115(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -1365,6 +2651,17 @@ define i1 @auto_gen_115(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_115_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_115_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp uge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_116(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_116(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -1376,6 +2673,17 @@ define i1 @auto_gen_116(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_116_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_116_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp ult double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_117(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_117(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -1387,6 +2695,17 @@ define i1 @auto_gen_117(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_117_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_117_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp ule double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_118(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_118(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -1398,6 +2717,17 @@ define i1 @auto_gen_118(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_118_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_118_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp une double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_119(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_119(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -1409,6 +2739,17 @@ define i1 @auto_gen_119(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_119_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_119_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp uno double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_120(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_120(
 ; CHECK-NEXT:    ret i1 false
@@ -1419,6 +2760,16 @@ define i1 @auto_gen_120(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_120_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_120_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_121(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_121(
 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
@@ -1430,6 +2781,17 @@ define i1 @auto_gen_121(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_121_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_121_logical(
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP1]]
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_122(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_122(
 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -1441,6 +2803,17 @@ define i1 @auto_gen_122(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_122_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_122_logical(
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP1]]
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_123(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_123(
 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
@@ -1452,6 +2825,17 @@ define i1 @auto_gen_123(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_123_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_123_logical(
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP1]]
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_124(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_124(
 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -1463,6 +2847,17 @@ define i1 @auto_gen_124(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_124_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_124_logical(
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP1]]
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_125(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_125(
 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
@@ -1474,6 +2869,17 @@ define i1 @auto_gen_125(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_125_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_125_logical(
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP1]]
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_126(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_126(
 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
@@ -1485,6 +2891,17 @@ define i1 @auto_gen_126(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_126_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_126_logical(
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP1]]
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_127(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_127(
 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
@@ -1496,6 +2913,17 @@ define i1 @auto_gen_127(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_127_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_127_logical(
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP1]]
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_128(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_128(
 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
@@ -1507,6 +2935,17 @@ define i1 @auto_gen_128(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_128_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_128_logical(
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP1]]
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_129(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_129(
 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
@@ -1518,6 +2957,17 @@ define i1 @auto_gen_129(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_129_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_129_logical(
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP1]]
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp ugt double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_130(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_130(
 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -1529,6 +2979,17 @@ define i1 @auto_gen_130(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_130_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_130_logical(
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP1]]
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp uge double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_131(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_131(
 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
@@ -1540,6 +3001,17 @@ define i1 @auto_gen_131(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_131_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_131_logical(
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP1]]
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp ult double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_132(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_132(
 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
@@ -1551,6 +3023,17 @@ define i1 @auto_gen_132(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_132_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_132_logical(
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP1]]
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp ule double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_133(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_133(
 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
@@ -1562,6 +3045,17 @@ define i1 @auto_gen_133(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_133_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_133_logical(
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP1]]
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp une double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_134(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_134(
 ; CHECK-NEXT:    [[CMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -1573,6 +3067,17 @@ define i1 @auto_gen_134(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_134_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_134_logical(
+; CHECK-NEXT:    [[CMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP1]]
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp uno double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}
+
 define i1 @auto_gen_135(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_135(
 ; CHECK-NEXT:    ret i1 true
@@ -1582,3 +3087,13 @@ define i1 @auto_gen_135(double %a, double %b) {
   %retval = and i1 %cmp, %cmp1
   ret i1 %retval
 }
+
+define i1 @auto_gen_135_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_135_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp true double %a, %b
+  %retval = select i1 %cmp, i1 %cmp1, i1 false
+  ret i1 %retval
+}

diff  --git a/llvm/test/Transforms/InstCombine/and-or-icmp-min-max.ll b/llvm/test/Transforms/InstCombine/and-or-icmp-min-max.ll
index 7f07147b14ff..e24bb5812302 100644
--- a/llvm/test/Transforms/InstCombine/and-or-icmp-min-max.ll
+++ b/llvm/test/Transforms/InstCombine/and-or-icmp-min-max.ll
@@ -23,6 +23,16 @@ define i1 @slt_and_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @slt_and_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @slt_and_max_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp slt i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 127
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define <2 x i1> @slt_and_max_commute(<2 x i8> %x, <2 x i8> %y)  {
 ; CHECK-LABEL: @slt_and_max_commute(
 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
@@ -43,6 +53,16 @@ define i1 @slt_swap_and_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @slt_swap_and_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @slt_swap_and_max_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp sgt i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 127
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @slt_swap_and_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @slt_swap_and_max_commute(
 ; CHECK-NEXT:    ret i1 false
@@ -53,6 +73,16 @@ define i1 @slt_swap_and_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @slt_swap_and_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @slt_swap_and_max_commute_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp sgt i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 127
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @ult_and_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_and_max(
 ; CHECK-NEXT:    ret i1 false
@@ -63,6 +93,16 @@ define i1 @ult_and_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ult_and_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ult_and_max_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp ult i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 255
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ult_and_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_and_max_commute(
 ; CHECK-NEXT:    ret i1 false
@@ -73,6 +113,16 @@ define i1 @ult_and_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ult_and_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ult_and_max_commute_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp ult i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 255
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @ult_swap_and_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_swap_and_max(
 ; CHECK-NEXT:    ret i1 false
@@ -83,6 +133,16 @@ define i1 @ult_swap_and_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ult_swap_and_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ult_swap_and_max_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp ugt i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 255
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ult_swap_and_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_swap_and_max_commute(
 ; CHECK-NEXT:    ret i1 false
@@ -93,6 +153,16 @@ define i1 @ult_swap_and_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ult_swap_and_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ult_swap_and_max_commute_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp ugt i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 255
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X == MIN) && (X > Y) --> false
@@ -109,6 +179,16 @@ define i1 @sgt_and_min(i9 %x, i9 %y)  {
   ret i1 %r
 }
 
+define i1 @sgt_and_min_logical(i9 %x, i9 %y)  {
+; CHECK-LABEL: @sgt_and_min_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp sgt i9 %x, %y
+  %cmpeq = icmp eq i9 %x, 256
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @sgt_and_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_and_min_commute(
 ; CHECK-NEXT:    ret i1 false
@@ -119,6 +199,16 @@ define i1 @sgt_and_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sgt_and_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sgt_and_min_commute_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp sgt i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 128
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @sgt_swap_and_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_swap_and_min(
 ; CHECK-NEXT:    ret i1 false
@@ -129,6 +219,16 @@ define i1 @sgt_swap_and_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sgt_swap_and_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sgt_swap_and_min_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp slt i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 128
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @sgt_swap_and_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_swap_and_min_commute(
 ; CHECK-NEXT:    ret i1 false
@@ -139,6 +239,16 @@ define i1 @sgt_swap_and_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sgt_swap_and_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sgt_swap_and_min_commute_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp slt i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 128
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @ugt_and_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ugt_and_min(
 ; CHECK-NEXT:    ret i1 false
@@ -149,6 +259,16 @@ define i1 @ugt_and_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_and_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ugt_and_min_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp ugt i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 0
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ugt_and_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ugt_and_min_commute(
 ; CHECK-NEXT:    ret i1 false
@@ -159,6 +279,16 @@ define i1 @ugt_and_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_and_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ugt_and_min_commute_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp ugt i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 0
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @ugt_swap_and_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ugt_swap_and_min(
 ; CHECK-NEXT:    ret i1 false
@@ -169,6 +299,16 @@ define i1 @ugt_swap_and_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_swap_and_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ugt_swap_and_min_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp ult i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 0
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ugt_swap_and_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ugt_swap_and_min_commute(
 ; CHECK-NEXT:    ret i1 false
@@ -179,6 +319,16 @@ define i1 @ugt_swap_and_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_swap_and_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ugt_swap_and_min_commute_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp ult i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 0
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X != MAX) || (X >= Y) --> true
@@ -195,6 +345,16 @@ define i1 @sge_or_not_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sge_or_not_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sge_or_not_max_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp sge i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 127
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @sge_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_or_not_max_commute(
 ; CHECK-NEXT:    ret i1 true
@@ -205,6 +365,16 @@ define i1 @sge_or_not_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sge_or_not_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sge_or_not_max_commute_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp sge i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 127
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @sge_swap_or_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_swap_or_not_max(
 ; CHECK-NEXT:    ret i1 true
@@ -215,6 +385,16 @@ define i1 @sge_swap_or_not_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sge_swap_or_not_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sge_swap_or_not_max_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp sle i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 127
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @sge_swap_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_swap_or_not_max_commute(
 ; CHECK-NEXT:    ret i1 true
@@ -225,6 +405,16 @@ define i1 @sge_swap_or_not_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sge_swap_or_not_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sge_swap_or_not_max_commute_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp sle i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 127
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @uge_or_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_or_not_max(
 ; CHECK-NEXT:    ret i1 true
@@ -235,6 +425,16 @@ define i1 @uge_or_not_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @uge_or_not_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @uge_or_not_max_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp uge i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 255
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @uge_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_or_not_max_commute(
 ; CHECK-NEXT:    ret i1 true
@@ -245,6 +445,16 @@ define i1 @uge_or_not_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @uge_or_not_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @uge_or_not_max_commute_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp uge i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 255
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @uge_swap_or_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_swap_or_not_max(
 ; CHECK-NEXT:    ret i1 true
@@ -255,6 +465,16 @@ define i1 @uge_swap_or_not_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @uge_swap_or_not_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @uge_swap_or_not_max_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp ule i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 255
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @uge_swap_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_swap_or_not_max_commute(
 ; CHECK-NEXT:    ret i1 true
@@ -265,6 +485,16 @@ define i1 @uge_swap_or_not_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @uge_swap_or_not_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @uge_swap_or_not_max_commute_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp ule i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 255
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X != MIN) || (X <= Y) --> true
@@ -281,6 +511,16 @@ define i1 @sle_or_not_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sle_or_not_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sle_or_not_min_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp sle i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 128
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @sle_or_not_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_or_not_min_commute(
 ; CHECK-NEXT:    ret i1 true
@@ -291,6 +531,16 @@ define i1 @sle_or_not_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sle_or_not_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sle_or_not_min_commute_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp sle i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 128
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @sle_swap_or_not_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_swap_or_not_min(
 ; CHECK-NEXT:    ret i1 true
@@ -301,6 +551,16 @@ define i1 @sle_swap_or_not_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sle_swap_or_not_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sle_swap_or_not_min_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp sge i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 128
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @sle_swap_or_not_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_swap_or_not_min_commute(
 ; CHECK-NEXT:    ret i1 true
@@ -311,6 +571,16 @@ define i1 @sle_swap_or_not_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sle_swap_or_not_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sle_swap_or_not_min_commute_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp sge i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 128
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @ule_or_not_min(i427 %x, i427 %y)  {
 ; CHECK-LABEL: @ule_or_not_min(
 ; CHECK-NEXT:    ret i1 true
@@ -321,6 +591,16 @@ define i1 @ule_or_not_min(i427 %x, i427 %y)  {
   ret i1 %r
 }
 
+define i1 @ule_or_not_min_logical(i427 %x, i427 %y)  {
+; CHECK-LABEL: @ule_or_not_min_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp ule i427 %x, %y
+  %cmpeq = icmp ne i427 %x, 0
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @ule_or_not_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ule_or_not_min_commute(
 ; CHECK-NEXT:    ret i1 true
@@ -331,6 +611,16 @@ define i1 @ule_or_not_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ule_or_not_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ule_or_not_min_commute_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp ule i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 0
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @ule_swap_or_not_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ule_swap_or_not_min(
 ; CHECK-NEXT:    ret i1 true
@@ -341,6 +631,16 @@ define i1 @ule_swap_or_not_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ule_swap_or_not_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ule_swap_or_not_min_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp uge i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 0
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @ule_swap_or_not_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ule_swap_or_not_min_commute(
 ; CHECK-NEXT:    ret i1 true
@@ -351,6 +651,16 @@ define i1 @ule_swap_or_not_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ule_swap_or_not_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ule_swap_or_not_min_commute_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp uge i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 0
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X == MAX) && (X >= Y) --> X == MAX
@@ -368,6 +678,17 @@ define i1 @sge_and_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sge_and_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sge_and_max_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp sge i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 127
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @sge_and_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_and_max_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 127
@@ -379,6 +700,17 @@ define i1 @sge_and_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sge_and_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sge_and_max_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp sge i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 127
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @sge_swap_and_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_swap_and_max(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 127
@@ -390,6 +722,17 @@ define i1 @sge_swap_and_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sge_swap_and_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sge_swap_and_max_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp sle i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 127
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @sge_swap_and_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_swap_and_max_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 127
@@ -401,6 +744,17 @@ define i1 @sge_swap_and_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sge_swap_and_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sge_swap_and_max_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp sle i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 127
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @uge_and_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_and_max(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -1
@@ -412,19 +766,41 @@ define i1 @uge_and_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
-define i1 @uge_and_max_commute(i8 %x, i8 %y)  {
-; CHECK-LABEL: @uge_and_max_commute(
+define i1 @uge_and_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @uge_and_max_logical(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -1
 ; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
   %cmp = icmp uge i8 %x, %y
   %cmpeq = icmp eq i8 %x, 255
-  %r = and i1 %cmpeq, %cmp
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
   ret i1 %r
 }
 
-define i1 @uge_swap_and_max(i8 %x, i8 %y)  {
-; CHECK-LABEL: @uge_swap_and_max(
+define i1 @uge_and_max_commute(i8 %x, i8 %y)  {
+; CHECK-LABEL: @uge_and_max_commute(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp uge i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 255
+  %r = and i1 %cmpeq, %cmp
+  ret i1 %r
+}
+
+define i1 @uge_and_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @uge_and_max_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp uge i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 255
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
+define i1 @uge_swap_and_max(i8 %x, i8 %y)  {
+; CHECK-LABEL: @uge_swap_and_max(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -1
 ; CHECK-NEXT:    ret i1 [[CMPEQ]]
 ;
@@ -434,6 +810,17 @@ define i1 @uge_swap_and_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @uge_swap_and_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @uge_swap_and_max_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ule i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 255
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @uge_swap_and_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_swap_and_max_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -1
@@ -445,6 +832,17 @@ define i1 @uge_swap_and_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @uge_swap_and_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @uge_swap_and_max_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ule i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 255
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X == MIN) && (X <= Y) --> X == MIN
@@ -462,6 +860,17 @@ define i1 @sle_and_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sle_and_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sle_and_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp sle i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 128
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @sle_and_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_and_min_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -128
@@ -473,6 +882,17 @@ define i1 @sle_and_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sle_and_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sle_and_min_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp sle i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 128
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @sle_swap_and_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_swap_and_min(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -128
@@ -484,6 +904,17 @@ define i1 @sle_swap_and_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sle_swap_and_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sle_swap_and_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp sge i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 128
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @sle_swap_and_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_swap_and_min_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -128
@@ -495,6 +926,17 @@ define i1 @sle_swap_and_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sle_swap_and_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sle_swap_and_min_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp sge i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 128
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @ule_and_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ule_and_min(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 0
@@ -506,6 +948,17 @@ define i1 @ule_and_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ule_and_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ule_and_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 0
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ule i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 0
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ule_and_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ule_and_min_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 0
@@ -517,6 +970,17 @@ define i1 @ule_and_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ule_and_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ule_and_min_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 0
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ule i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 0
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @ule_swap_and_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ule_swap_and_min(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 0
@@ -528,6 +992,17 @@ define i1 @ule_swap_and_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ule_swap_and_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ule_swap_and_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 0
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp uge i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 0
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ule_swap_and_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ule_swap_and_min_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 0
@@ -539,6 +1014,17 @@ define i1 @ule_swap_and_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ule_swap_and_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ule_swap_and_min_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8 [[X:%.*]], 0
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp uge i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 0
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X == MAX) || (X >= Y) --> X >= Y
@@ -556,6 +1042,17 @@ define i1 @sge_or_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sge_or_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sge_or_max_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp sge i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 127
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @sge_or_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_or_max_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
@@ -567,6 +1064,17 @@ define i1 @sge_or_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sge_or_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sge_or_max_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp sge i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 127
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @sge_swap_or_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_swap_or_max(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8 [[Y:%.*]], [[X:%.*]]
@@ -578,6 +1086,17 @@ define i1 @sge_swap_or_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sge_swap_or_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sge_swap_or_max_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp sle i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 127
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @sge_swap_or_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sge_swap_or_max_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8 [[Y:%.*]], [[X:%.*]]
@@ -589,6 +1108,17 @@ define i1 @sge_swap_or_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sge_swap_or_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sge_swap_or_max_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp sle i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 127
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @uge_or_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_or_max(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
@@ -600,6 +1130,17 @@ define i1 @uge_or_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @uge_or_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @uge_or_max_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp uge i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 255
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @uge_or_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_or_max_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
@@ -611,6 +1152,17 @@ define i1 @uge_or_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @uge_or_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @uge_or_max_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp uge i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 255
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @uge_swap_or_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_swap_or_max(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
@@ -622,6 +1174,17 @@ define i1 @uge_swap_or_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @uge_swap_or_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @uge_swap_or_max_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ule i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 255
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @uge_swap_or_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @uge_swap_or_max_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
@@ -633,6 +1196,17 @@ define i1 @uge_swap_or_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @uge_swap_or_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @uge_swap_or_max_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ule i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 255
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X == MIN) || (X <= Y) --> X <= Y
@@ -650,6 +1224,17 @@ define i1 @sle_or_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sle_or_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sle_or_min_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp sle i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 128
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @sle_or_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_or_min_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
@@ -661,6 +1246,17 @@ define i1 @sle_or_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sle_or_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sle_or_min_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp sle i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 128
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @sle_swap_or_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_swap_or_min(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[Y:%.*]], [[X:%.*]]
@@ -672,6 +1268,17 @@ define i1 @sle_swap_or_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sle_swap_or_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sle_swap_or_min_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp sge i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 128
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @sle_swap_or_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sle_swap_or_min_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[Y:%.*]], [[X:%.*]]
@@ -683,6 +1290,17 @@ define i1 @sle_swap_or_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sle_swap_or_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sle_swap_or_min_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp sge i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 128
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @ule_or_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ule_or_min(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[X:%.*]], [[Y:%.*]]
@@ -694,6 +1312,17 @@ define i1 @ule_or_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ule_or_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ule_or_min_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ule i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 0
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @ule_or_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ule_or_min_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[X:%.*]], [[Y:%.*]]
@@ -705,6 +1334,17 @@ define i1 @ule_or_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ule_or_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ule_or_min_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ule i8 %x, %y
+  %cmpeq = icmp eq i8 %x, 0
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @ule_swap_or_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ule_swap_or_min(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[Y:%.*]], [[X:%.*]]
@@ -716,6 +1356,17 @@ define i1 @ule_swap_or_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ule_swap_or_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ule_swap_or_min_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp uge i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 0
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @ule_swap_or_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ule_swap_or_min_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[Y:%.*]], [[X:%.*]]
@@ -727,6 +1378,17 @@ define i1 @ule_swap_or_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ule_swap_or_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ule_swap_or_min_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp uge i8 %y, %x
+  %cmpeq = icmp eq i8 %x, 0
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X != MAX) && (X < Y) --> X < Y
@@ -744,6 +1406,17 @@ define i1 @slt_and_not_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @slt_and_not_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @slt_and_not_max_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp slt i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 127
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @slt_and_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @slt_and_not_max_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
@@ -755,6 +1428,17 @@ define i1 @slt_and_not_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @slt_and_not_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @slt_and_not_max_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp slt i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 127
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @slt_swap_and_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @slt_swap_and_not_max(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[Y:%.*]], [[X:%.*]]
@@ -766,6 +1450,17 @@ define i1 @slt_swap_and_not_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @slt_swap_and_not_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @slt_swap_and_not_max_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp sgt i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 127
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @slt_swap_and_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @slt_swap_and_not_max_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[Y:%.*]], [[X:%.*]]
@@ -777,6 +1472,17 @@ define i1 @slt_swap_and_not_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @slt_swap_and_not_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @slt_swap_and_not_max_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp sgt i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 127
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @ult_and_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_and_not_max(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
@@ -788,6 +1494,17 @@ define i1 @ult_and_not_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ult_and_not_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ult_and_not_max_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ult i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 255
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ult_and_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_and_not_max_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
@@ -799,6 +1516,17 @@ define i1 @ult_and_not_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ult_and_not_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ult_and_not_max_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ult i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 255
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @ult_swap_and_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_swap_and_not_max(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[Y:%.*]], [[X:%.*]]
@@ -810,6 +1538,17 @@ define i1 @ult_swap_and_not_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ult_swap_and_not_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ult_swap_and_not_max_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ugt i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 255
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ult_swap_and_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_swap_and_not_max_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[Y:%.*]], [[X:%.*]]
@@ -821,6 +1560,17 @@ define i1 @ult_swap_and_not_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ult_swap_and_not_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ult_swap_and_not_max_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ugt i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 255
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X != MIN) && (X > Y) --> X > Y
@@ -838,6 +1588,17 @@ define i1 @sgt_and_not_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sgt_and_not_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sgt_and_not_min_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp sgt i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 128
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @sgt_and_not_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_and_not_min_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
@@ -849,6 +1610,17 @@ define i1 @sgt_and_not_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sgt_and_not_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sgt_and_not_min_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp sgt i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 128
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @sgt_swap_and_not_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_swap_and_not_min(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
@@ -860,6 +1632,17 @@ define i1 @sgt_swap_and_not_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sgt_swap_and_not_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sgt_swap_and_not_min_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp slt i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 128
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @sgt_swap_and_not_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_swap_and_not_min_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
@@ -871,6 +1654,17 @@ define i1 @sgt_swap_and_not_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sgt_swap_and_not_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sgt_swap_and_not_min_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp slt i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 128
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @ugt_and_not_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ugt_and_not_min(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
@@ -882,6 +1676,17 @@ define i1 @ugt_and_not_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_and_not_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ugt_and_not_min_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ugt i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 0
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ugt_and_not_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ugt_and_not_min_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
@@ -893,6 +1698,17 @@ define i1 @ugt_and_not_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_and_not_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ugt_and_not_min_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ugt i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 0
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @ugt_swap_and_not_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ugt_swap_and_not_min(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[Y:%.*]], [[X:%.*]]
@@ -904,6 +1720,17 @@ define i1 @ugt_swap_and_not_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_swap_and_not_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ugt_swap_and_not_min_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ult i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 0
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ugt_swap_and_not_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ugt_swap_and_not_min_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[Y:%.*]], [[X:%.*]]
@@ -915,6 +1742,17 @@ define i1 @ugt_swap_and_not_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_swap_and_not_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ugt_swap_and_not_min_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ult i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 0
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X != MAX) || (X < Y) --> X != MAX
@@ -932,6 +1770,17 @@ define i1 @slt_or_not_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @slt_or_not_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @slt_or_not_max_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp slt i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 127
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @slt_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @slt_or_not_max_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 127
@@ -943,6 +1792,17 @@ define i1 @slt_or_not_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @slt_or_not_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @slt_or_not_max_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp slt i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 127
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @slt_swap_or_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @slt_swap_or_not_max(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 127
@@ -954,6 +1814,17 @@ define i1 @slt_swap_or_not_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @slt_swap_or_not_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @slt_swap_or_not_max_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp sgt i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 127
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @slt_swap_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @slt_swap_or_not_max_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 127
@@ -965,6 +1836,17 @@ define i1 @slt_swap_or_not_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @slt_swap_or_not_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @slt_swap_or_not_max_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 127
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp sgt i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 127
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @ult_or_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_or_not_max(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -1
@@ -976,6 +1858,17 @@ define i1 @ult_or_not_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ult_or_not_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ult_or_not_max_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ult i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 255
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @ult_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_or_not_max_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -1
@@ -987,6 +1880,17 @@ define i1 @ult_or_not_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ult_or_not_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ult_or_not_max_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ult i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 255
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @ult_swap_or_not_max(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_swap_or_not_max(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -1
@@ -998,6 +1902,17 @@ define i1 @ult_swap_or_not_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ult_swap_or_not_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ult_swap_or_not_max_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ugt i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 255
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @ult_swap_or_not_max_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ult_swap_or_not_max_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -1
@@ -1009,6 +1924,17 @@ define i1 @ult_swap_or_not_max_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ult_swap_or_not_max_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ult_swap_or_not_max_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ugt i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 255
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X != MIN) || (X > Y) --> X != MIN
@@ -1026,6 +1952,17 @@ define i1 @sgt_or_not_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sgt_or_not_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sgt_or_not_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp sgt i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 128
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @sgt_or_not_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_or_not_min_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -128
@@ -1037,6 +1974,17 @@ define i1 @sgt_or_not_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sgt_or_not_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sgt_or_not_min_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp sgt i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 128
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @sgt_swap_or_not_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_swap_or_not_min(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -128
@@ -1048,6 +1996,17 @@ define i1 @sgt_swap_or_not_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sgt_swap_or_not_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sgt_swap_or_not_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp slt i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 128
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @sgt_swap_or_not_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @sgt_swap_or_not_min_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -128
@@ -1059,6 +2018,17 @@ define i1 @sgt_swap_or_not_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sgt_swap_or_not_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sgt_swap_or_not_min_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], -128
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp slt i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 128
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @ugt_or_not_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ugt_or_not_min(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 0
@@ -1070,6 +2040,17 @@ define i1 @ugt_or_not_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_or_not_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ugt_or_not_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 0
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ugt i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 0
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @ugt_or_not_min_commute(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ugt_or_not_min_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 0
@@ -1081,6 +2062,17 @@ define i1 @ugt_or_not_min_commute(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_or_not_min_commute_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ugt_or_not_min_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 0
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ugt i8 %x, %y
+  %cmpeq = icmp ne i8 %x, 0
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @ugt_swap_or_not_min(i8 %x, i8 %y)  {
 ; CHECK-LABEL: @ugt_swap_or_not_min(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 0
@@ -1092,6 +2084,17 @@ define i1 @ugt_swap_or_not_min(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_swap_or_not_min_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @ugt_swap_or_not_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8 [[X:%.*]], 0
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ult i8 %y, %x
+  %cmpeq = icmp ne i8 %x, 0
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @ugt_swap_or_not_min_commute(i823 %x, i823 %y)  {
 ; CHECK-LABEL: @ugt_swap_or_not_min_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i823 [[X:%.*]], 0
@@ -1102,3 +2105,14 @@ define i1 @ugt_swap_or_not_min_commute(i823 %x, i823 %y)  {
   %r = or i1 %cmpeq, %cmp
   ret i1 %r
 }
+
+define i1 @ugt_swap_or_not_min_commute_logical(i823 %x, i823 %y)  {
+; CHECK-LABEL: @ugt_swap_or_not_min_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i823 [[X:%.*]], 0
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ult i823 %y, %x
+  %cmpeq = icmp ne i823 %x, 0
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}

diff  --git a/llvm/test/Transforms/InstCombine/and-or-icmp-nullptr.ll b/llvm/test/Transforms/InstCombine/and-or-icmp-nullptr.ll
index be573281eb8c..b8a43c57bf58 100644
--- a/llvm/test/Transforms/InstCombine/and-or-icmp-nullptr.ll
+++ b/llvm/test/Transforms/InstCombine/and-or-icmp-nullptr.ll
@@ -26,6 +26,16 @@ define i1 @ugt_and_min(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_and_min_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ugt_and_min_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp ugt i8* %x, %y
+  %cmpeq = icmp eq i8* %x, null
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ugt_and_min_commute(<2 x i8>* %x, <2 x i8>* %y)  {
 ; CHECK-LABEL: @ugt_and_min_commute(
 ; CHECK-NEXT:    ret i1 false
@@ -36,6 +46,16 @@ define i1 @ugt_and_min_commute(<2 x i8>* %x, <2 x i8>* %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_and_min_commute_logical(<2 x i8>* %x, <2 x i8>* %y)  {
+; CHECK-LABEL: @ugt_and_min_commute_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp ugt <2 x i8>* %x, %y
+  %cmpeq = icmp eq <2 x i8>* %x, null
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @ugt_swap_and_min(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @ugt_swap_and_min(
 ; CHECK-NEXT:    ret i1 false
@@ -46,6 +66,16 @@ define i1 @ugt_swap_and_min(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_swap_and_min_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ugt_swap_and_min_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp ult i8* %y, %x
+  %cmpeq = icmp eq i8* %x, null
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ugt_swap_and_min_commute(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @ugt_swap_and_min_commute(
 ; CHECK-NEXT:    ret i1 false
@@ -56,6 +86,16 @@ define i1 @ugt_swap_and_min_commute(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_swap_and_min_commute_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ugt_swap_and_min_commute_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = icmp ult i8* %y, %x
+  %cmpeq = icmp eq i8* %x, null
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X != null) || (X <= Y) --> true
@@ -72,6 +112,16 @@ define i1 @ule_or_not_min(i427* %x, i427* %y)  {
   ret i1 %r
 }
 
+define i1 @ule_or_not_min_logical(i427* %x, i427* %y)  {
+; CHECK-LABEL: @ule_or_not_min_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp ule i427* %x, %y
+  %cmpeq = icmp ne i427* %x, null
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @ule_or_not_min_commute(<3 x i9>* %x, <3 x i9>* %y)  {
 ; CHECK-LABEL: @ule_or_not_min_commute(
 ; CHECK-NEXT:    ret i1 true
@@ -82,6 +132,16 @@ define i1 @ule_or_not_min_commute(<3 x i9>* %x, <3 x i9>* %y)  {
   ret i1 %r
 }
 
+define i1 @ule_or_not_min_commute_logical(<3 x i9>* %x, <3 x i9>* %y)  {
+; CHECK-LABEL: @ule_or_not_min_commute_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp ule <3 x i9>* %x, %y
+  %cmpeq = icmp ne <3 x i9>* %x, null
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @ule_swap_or_not_min(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @ule_swap_or_not_min(
 ; CHECK-NEXT:    ret i1 true
@@ -92,6 +152,16 @@ define i1 @ule_swap_or_not_min(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ule_swap_or_not_min_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ule_swap_or_not_min_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp uge i8* %y, %x
+  %cmpeq = icmp ne i8* %x, null
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @ule_swap_or_not_min_commute(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @ule_swap_or_not_min_commute(
 ; CHECK-NEXT:    ret i1 true
@@ -102,6 +172,16 @@ define i1 @ule_swap_or_not_min_commute(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ule_swap_or_not_min_commute_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ule_swap_or_not_min_commute_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = icmp uge i8* %y, %x
+  %cmpeq = icmp ne i8* %x, null
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X == null) && (X <= Y) --> X == null
@@ -119,6 +199,17 @@ define i1 @ule_and_min(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ule_and_min_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ule_and_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8* [[X:%.*]], null
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ule i8* %x, %y
+  %cmpeq = icmp eq i8* %x, null
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ule_and_min_commute(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @ule_and_min_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8* [[X:%.*]], null
@@ -130,6 +221,17 @@ define i1 @ule_and_min_commute(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ule_and_min_commute_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ule_and_min_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8* [[X:%.*]], null
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ule i8* %x, %y
+  %cmpeq = icmp eq i8* %x, null
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @ule_swap_and_min(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @ule_swap_and_min(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8* [[X:%.*]], null
@@ -141,6 +243,17 @@ define i1 @ule_swap_and_min(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ule_swap_and_min_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ule_swap_and_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8* [[X:%.*]], null
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp uge i8* %y, %x
+  %cmpeq = icmp eq i8* %x, null
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ule_swap_and_min_commute(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @ule_swap_and_min_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8* [[X:%.*]], null
@@ -152,6 +265,17 @@ define i1 @ule_swap_and_min_commute(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ule_swap_and_min_commute_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ule_swap_and_min_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8* [[X:%.*]], null
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp uge i8* %y, %x
+  %cmpeq = icmp eq i8* %x, null
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X == null) || (X <= Y) --> X <= Y
@@ -169,6 +293,17 @@ define i1 @ule_or_min(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ule_or_min_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ule_or_min_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8* [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ule i8* %x, %y
+  %cmpeq = icmp eq i8* %x, null
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @ule_or_min_commute(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @ule_or_min_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8* [[X:%.*]], [[Y:%.*]]
@@ -180,6 +315,17 @@ define i1 @ule_or_min_commute(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ule_or_min_commute_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ule_or_min_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i8* [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ule i8* %x, %y
+  %cmpeq = icmp eq i8* %x, null
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @ule_swap_or_min(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @ule_swap_or_min(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8* [[Y:%.*]], [[X:%.*]]
@@ -191,6 +337,17 @@ define i1 @ule_swap_or_min(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ule_swap_or_min_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ule_swap_or_min_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8* [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp uge i8* %y, %x
+  %cmpeq = icmp eq i8* %x, null
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @ule_swap_or_min_commute(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @ule_swap_or_min_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8* [[Y:%.*]], [[X:%.*]]
@@ -202,6 +359,17 @@ define i1 @ule_swap_or_min_commute(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ule_swap_or_min_commute_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ule_swap_or_min_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i8* [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp uge i8* %y, %x
+  %cmpeq = icmp eq i8* %x, null
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X != null) && (X > Y) --> X > Y
@@ -219,6 +387,17 @@ define i1 @ugt_and_not_min(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_and_not_min_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ugt_and_not_min_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8* [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ugt i8* %x, %y
+  %cmpeq = icmp ne i8* %x, null
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ugt_and_not_min_commute(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @ugt_and_not_min_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8* [[X:%.*]], [[Y:%.*]]
@@ -230,6 +409,17 @@ define i1 @ugt_and_not_min_commute(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_and_not_min_commute_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ugt_and_not_min_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8* [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ugt i8* %x, %y
+  %cmpeq = icmp ne i8* %x, null
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define i1 @ugt_swap_and_not_min(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @ugt_swap_and_not_min(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8* [[Y:%.*]], [[X:%.*]]
@@ -241,6 +431,17 @@ define i1 @ugt_swap_and_not_min(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_swap_and_not_min_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ugt_swap_and_not_min_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8* [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ult i8* %y, %x
+  %cmpeq = icmp ne i8* %x, null
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @ugt_swap_and_not_min_commute(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @ugt_swap_and_not_min_commute(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8* [[Y:%.*]], [[X:%.*]]
@@ -252,6 +453,17 @@ define i1 @ugt_swap_and_not_min_commute(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_swap_and_not_min_commute_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ugt_swap_and_not_min_commute_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8* [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = icmp ult i8* %y, %x
+  %cmpeq = icmp ne i8* %x, null
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;
 ; (X != null) || (X > Y) --> X != null
@@ -269,6 +481,17 @@ define i1 @ugt_or_not_min(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_or_not_min_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ugt_or_not_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8* [[X:%.*]], null
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ugt i8* %x, %y
+  %cmpeq = icmp ne i8* %x, null
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @ugt_or_not_min_commute(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @ugt_or_not_min_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8* [[X:%.*]], null
@@ -280,6 +503,17 @@ define i1 @ugt_or_not_min_commute(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_or_not_min_commute_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ugt_or_not_min_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8* [[X:%.*]], null
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ugt i8* %x, %y
+  %cmpeq = icmp ne i8* %x, null
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @ugt_swap_or_not_min(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @ugt_swap_or_not_min(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8* [[X:%.*]], null
@@ -291,6 +525,17 @@ define i1 @ugt_swap_or_not_min(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_swap_or_not_min_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @ugt_swap_or_not_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8* [[X:%.*]], null
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ult i8* %y, %x
+  %cmpeq = icmp ne i8* %x, null
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @ugt_swap_or_not_min_commute(i823* %x, i823* %y)  {
 ; CHECK-LABEL: @ugt_swap_or_not_min_commute(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i823* [[X:%.*]], null
@@ -302,6 +547,17 @@ define i1 @ugt_swap_or_not_min_commute(i823* %x, i823* %y)  {
   ret i1 %r
 }
 
+define i1 @ugt_swap_or_not_min_commute_logical(i823* %x, i823* %y)  {
+; CHECK-LABEL: @ugt_swap_or_not_min_commute_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i823* [[X:%.*]], null
+; CHECK-NEXT:    ret i1 [[CMPEQ]]
+;
+  %cmp = icmp ult i823* %y, %x
+  %cmpeq = icmp ne i823* %x, null
+  %r = select i1 %cmpeq, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @sgt_and_min(i9* %x, i9* %y)  {
 ; CHECK-LABEL: @sgt_and_min(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i9* [[X:%.*]], null
@@ -315,6 +571,19 @@ define i1 @sgt_and_min(i9* %x, i9* %y)  {
   ret i1 %r
 }
 
+define i1 @sgt_and_min_logical(i9* %x, i9* %y)  {
+; CHECK-LABEL: @sgt_and_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i9* [[X:%.*]], null
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i9* [[Y:%.*]], null
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[CMPEQ]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp = icmp sgt i9* %x, %y
+  %cmpeq = icmp eq i9* %x, null
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @sle_or_not_min(i427* %x, i427* %y)  {
 ; CHECK-LABEL: @sle_or_not_min(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i427* [[X:%.*]], null
@@ -328,6 +597,19 @@ define i1 @sle_or_not_min(i427* %x, i427* %y)  {
   ret i1 %r
 }
 
+define i1 @sle_or_not_min_logical(i427* %x, i427* %y)  {
+; CHECK-LABEL: @sle_or_not_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i427* [[X:%.*]], null
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sge i427* [[Y:%.*]], null
+; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[CMPEQ]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp = icmp sle i427* %x, %y
+  %cmpeq = icmp ne i427* %x, null
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @sle_and_min(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @sle_and_min(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8* [[X:%.*]], null
@@ -341,6 +623,19 @@ define i1 @sle_and_min(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @sle_and_min_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @sle_and_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8* [[X:%.*]], null
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sge i8* [[Y:%.*]], null
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[CMPEQ]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp = icmp sle i8* %x, %y
+  %cmpeq = icmp eq i8* %x, null
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @sgt_and_not_min(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @sgt_and_not_min(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8* [[X:%.*]], [[Y:%.*]]
@@ -354,6 +649,19 @@ define i1 @sgt_and_not_min(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @sgt_and_not_min_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @sgt_and_not_min_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8* [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8* [[X]], null
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %cmp = icmp sgt i8* %x, %y
+  %cmpeq = icmp ne i8* %x, null
+  %r = select i1 %cmp, i1 %cmpeq, i1 false
+  ret i1 %r
+}
+
 define i1 @sgt_or_not_min(i8* %x, i8* %y)  {
 ; CHECK-LABEL: @sgt_or_not_min(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8* [[X:%.*]], null
@@ -367,6 +675,19 @@ define i1 @sgt_or_not_min(i8* %x, i8* %y)  {
   ret i1 %r
 }
 
+define i1 @sgt_or_not_min_logical(i8* %x, i8* %y)  {
+; CHECK-LABEL: @sgt_or_not_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne i8* [[X:%.*]], null
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8* [[Y:%.*]], null
+; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[CMPEQ]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp = icmp sgt i8* %x, %y
+  %cmpeq = icmp ne i8* %x, null
+  %r = select i1 %cmp, i1 true, i1 %cmpeq
+  ret i1 %r
+}
+
 define i1 @slt_and_min(i8* %a, i8* %b) {
 ; CHECK-LABEL: @slt_and_min(
 ; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8* [[A:%.*]], null
@@ -379,3 +700,16 @@ define i1 @slt_and_min(i8* %a, i8* %b) {
   %r = and i1 %cmpeq, %cmp
   ret i1 %r
 }
+
+define i1 @slt_and_min_logical(i8* %a, i8* %b) {
+; CHECK-LABEL: @slt_and_min_logical(
+; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq i8* [[A:%.*]], null
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i8* [[B:%.*]], null
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[CMPEQ]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmpeq = icmp eq i8* %a, null
+  %cmp = icmp slt i8* %a, %b
+  %r = select i1 %cmpeq, i1 %cmp, i1 false
+  ret i1 %r
+}

diff  --git a/llvm/test/Transforms/InstCombine/and-or-icmps.ll b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
index a62790bd57f4..0e8f0ca7bf96 100644
--- a/llvm/test/Transforms/InstCombine/and-or-icmps.ll
+++ b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
@@ -14,6 +14,17 @@ define i1 @PR1817_1(i32 %X) {
   ret i1 %C
 }
 
+define i1 @PR1817_1_logical(i32 %X) {
+; CHECK-LABEL: @PR1817_1_logical(
+; CHECK-NEXT:    [[B:%.*]] = icmp ult i32 [[X:%.*]], 10
+; CHECK-NEXT:    ret i1 [[B]]
+;
+  %A = icmp slt i32 %X, 10
+  %B = icmp ult i32 %X, 10
+  %C = select i1 %A, i1 %B, i1 false
+  ret i1 %C
+}
+
 define i1 @PR1817_2(i32 %X) {
 ; CHECK-LABEL: @PR1817_2(
 ; CHECK-NEXT:    [[A:%.*]] = icmp slt i32 [[X:%.*]], 10
@@ -25,6 +36,17 @@ define i1 @PR1817_2(i32 %X) {
   ret i1 %C
 }
 
+define i1 @PR1817_2_logical(i32 %X) {
+; CHECK-LABEL: @PR1817_2_logical(
+; CHECK-NEXT:    [[A:%.*]] = icmp slt i32 [[X:%.*]], 10
+; CHECK-NEXT:    ret i1 [[A]]
+;
+  %A = icmp slt i32 %X, 10
+  %B = icmp ult i32 %X, 10
+  %C = select i1 %A, i1 true, i1 %B
+  ret i1 %C
+}
+
 define i1 @PR2330(i32 %a, i32 %b) {
 ; CHECK-LABEL: @PR2330(
 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
@@ -37,6 +59,18 @@ define i1 @PR2330(i32 %a, i32 %b) {
   ret i1 %and
 }
 
+define i1 @PR2330_logical(i32 %a, i32 %b) {
+; CHECK-LABEL: @PR2330_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 8
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp1 = icmp ult i32 %a, 8
+  %cmp2 = icmp ult i32 %b, 8
+  %and = select i1 %cmp2, i1 %cmp1, i1 false
+  ret i1 %and
+}
+
 ; if LHSC and RHSC 
diff er only by one bit:
 ; (X == C1 || X == C2) -> (X & ~(C1 ^ C2)) == C1 (C1 has 1 less set bit)
 ; PR14708: https://bugs.llvm.org/show_bug.cgi?id=14708
@@ -53,6 +87,18 @@ define i1 @or_eq_with_one_bit_
diff _constants1(i32 %x) {
   ret i1 %or
 }
 
+define i1 @or_eq_with_one_bit_
diff _constants1_logical(i32 %x) {
+; CHECK-LABEL: @or_eq_with_one_bit_
diff _constants1_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 50
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp1 = icmp eq i32 %x, 50
+  %cmp2 = icmp eq i32 %x, 51
+  %or = select i1 %cmp1, i1 true, i1 %cmp2
+  ret i1 %or
+}
+
 ; (X != C1 && X != C2) -> (X & ~(C1 ^ C2)) != C1 (C1 has 1 less set bit)
 
 define i1 @and_ne_with_one_bit_
diff _constants1(i32 %x) {
@@ -67,6 +113,18 @@ define i1 @and_ne_with_one_bit_
diff _constants1(i32 %x) {
   ret i1 %and
 }
 
+define i1 @and_ne_with_one_bit_
diff _constants1_logical(i32 %x) {
+; CHECK-LABEL: @and_ne_with_one_bit_
diff _constants1_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 50
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp1 = icmp ne i32 %x, 51
+  %cmp2 = icmp ne i32 %x, 50
+  %and = select i1 %cmp1, i1 %cmp2, i1 false
+  ret i1 %and
+}
+
 ; The constants are not necessarily off-by-one, just off-by-one-bit.
 
 define i1 @or_eq_with_one_bit_
diff _constants2(i32 %x) {
@@ -81,6 +139,18 @@ define i1 @or_eq_with_one_bit_
diff _constants2(i32 %x) {
   ret i1 %or
 }
 
+define i1 @or_eq_with_one_bit_
diff _constants2_logical(i32 %x) {
+; CHECK-LABEL: @or_eq_with_one_bit_
diff _constants2_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -33
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 65
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp1 = icmp eq i32 %x, 97
+  %cmp2 = icmp eq i32 %x, 65
+  %or = select i1 %cmp1, i1 true, i1 %cmp2
+  ret i1 %or
+}
+
 define i1 @and_ne_with_one_bit_
diff _constants2(i19 %x) {
 ; CHECK-LABEL: @and_ne_with_one_bit_
diff _constants2(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i19 [[X:%.*]], -129
@@ -93,6 +163,18 @@ define i1 @and_ne_with_one_bit_
diff _constants2(i19 %x) {
   ret i1 %and
 }
 
+define i1 @and_ne_with_one_bit_
diff _constants2_logical(i19 %x) {
+; CHECK-LABEL: @and_ne_with_one_bit_
diff _constants2_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i19 [[X:%.*]], -129
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i19 [[TMP1]], 65
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp1 = icmp ne i19 %x, 65
+  %cmp2 = icmp ne i19 %x, 193
+  %and = select i1 %cmp1, i1 %cmp2, i1 false
+  ret i1 %and
+}
+
 ; Make sure the constants are treated as unsigned when comparing them.
 
 define i1 @or_eq_with_one_bit_
diff _constants3(i8 %x) {
@@ -107,6 +189,18 @@ define i1 @or_eq_with_one_bit_
diff _constants3(i8 %x) {
   ret i1 %or
 }
 
+define i1 @or_eq_with_one_bit_
diff _constants3_logical(i8 %x) {
+; CHECK-LABEL: @or_eq_with_one_bit_
diff _constants3_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], 127
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 126
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp1 = icmp eq i8 %x, 254
+  %cmp2 = icmp eq i8 %x, 126
+  %or = select i1 %cmp1, i1 true, i1 %cmp2
+  ret i1 %or
+}
+
 define i1 @and_ne_with_one_bit_
diff _constants3(i8 %x) {
 ; CHECK-LABEL: @and_ne_with_one_bit_
diff _constants3(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], 127
@@ -119,6 +213,18 @@ define i1 @and_ne_with_one_bit_
diff _constants3(i8 %x) {
   ret i1 %and
 }
 
+define i1 @and_ne_with_one_bit_
diff _constants3_logical(i8 %x) {
+; CHECK-LABEL: @and_ne_with_one_bit_
diff _constants3_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], 127
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 65
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp1 = icmp ne i8 %x, 65
+  %cmp2 = icmp ne i8 %x, 193
+  %and = select i1 %cmp1, i1 %cmp2, i1 false
+  ret i1 %and
+}
+
 ; Use an 'add' to eliminate an icmp if the constants are off-by-one (not off-by-one-bit).
 ; (X == 13 | X == 14) -> X-13 <u 2
 
@@ -134,6 +240,18 @@ define i1 @or_eq_with_
diff _one(i8 %x) {
   ret i1 %or
 }
 
+define i1 @or_eq_with_
diff _one_logical(i8 %x) {
+; CHECK-LABEL: @or_eq_with_
diff _one_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X:%.*]], -13
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], 2
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp1 = icmp eq i8 %x, 13
+  %cmp2 = icmp eq i8 %x, 14
+  %or = select i1 %cmp1, i1 true, i1 %cmp2
+  ret i1 %or
+}
+
 ; (X != 40 | X != 39) -> X-39 >u 1
 
 define i1 @and_ne_with_
diff _one(i32 %x) {
@@ -148,6 +266,18 @@ define i1 @and_ne_with_
diff _one(i32 %x) {
   ret i1 %and
 }
 
+define i1 @and_ne_with_
diff _one_logical(i32 %x) {
+; CHECK-LABEL: @and_ne_with_
diff _one_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -39
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i32 [[TMP1]], 1
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp1 = icmp ne i32 %x, 40
+  %cmp2 = icmp ne i32 %x, 39
+  %and = select i1 %cmp1, i1 %cmp2, i1 false
+  ret i1 %and
+}
+
 ; Make sure the constants are treated as signed when comparing them.
 ; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524
 
@@ -163,6 +293,18 @@ define i1 @or_eq_with_
diff _one_signed(i32 %x) {
   ret i1 %or
 }
 
+define i1 @or_eq_with_
diff _one_signed_logical(i32 %x) {
+; CHECK-LABEL: @or_eq_with_
diff _one_signed_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 1
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 2
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp1 = icmp eq i32 %x, 0
+  %cmp2 = icmp eq i32 %x, -1
+  %or = select i1 %cmp1, i1 true, i1 %cmp2
+  ret i1 %or
+}
+
 define i1 @and_ne_with_
diff _one_signed(i64 %x) {
 ; CHECK-LABEL: @and_ne_with_
diff _one_signed(
 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[X:%.*]], 1
@@ -175,6 +317,18 @@ define i1 @and_ne_with_
diff _one_signed(i64 %x) {
   ret i1 %and
 }
 
+define i1 @and_ne_with_
diff _one_signed_logical(i64 %x) {
+; CHECK-LABEL: @and_ne_with_
diff _one_signed_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[X:%.*]], 1
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i64 [[TMP1]], 1
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp1 = icmp ne i64 %x, -1
+  %cmp2 = icmp ne i64 %x, 0
+  %and = select i1 %cmp1, i1 %cmp2, i1 false
+  ret i1 %and
+}
+
 ; Vectors with splat constants get the same folds.
 
 define <2 x i1> @or_eq_with_one_bit_
diff _constants2_splatvec(<2 x i32> %x) {
@@ -274,6 +428,17 @@ define i1 @PR42691_1(i32 %x) {
   ret i1 %c
 }
 
+define i1 @PR42691_1_logical(i32 %x) {
+; CHECK-LABEL: @PR42691_1_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X:%.*]], 2147483646
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %c1 = icmp slt i32 %x, 0
+  %c2 = icmp eq i32 %x, 2147483647
+  %c = select i1 %c1, i1 true, i1 %c2
+  ret i1 %c
+}
+
 define i1 @PR42691_2(i32 %x) {
 ; CHECK-LABEL: @PR42691_2(
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -2
@@ -285,6 +450,17 @@ define i1 @PR42691_2(i32 %x) {
   ret i1 %c
 }
 
+define i1 @PR42691_2_logical(i32 %x) {
+; CHECK-LABEL: @PR42691_2_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -2
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %c1 = icmp ult i32 %x, 2147483648
+  %c2 = icmp eq i32 %x, 4294967295
+  %c = select i1 %c1, i1 true, i1 %c2
+  ret i1 %c
+}
+
 define i1 @PR42691_3(i32 %x) {
 ; CHECK-LABEL: @PR42691_3(
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X:%.*]], -2147483647
@@ -296,6 +472,17 @@ define i1 @PR42691_3(i32 %x) {
   ret i1 %c
 }
 
+define i1 @PR42691_3_logical(i32 %x) {
+; CHECK-LABEL: @PR42691_3_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X:%.*]], -2147483647
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %c1 = icmp sge i32 %x, 0
+  %c2 = icmp eq i32 %x, -2147483648
+  %c = select i1 %c1, i1 true, i1 %c2
+  ret i1 %c
+}
+
 define i1 @PR42691_4(i32 %x) {
 ; CHECK-LABEL: @PR42691_4(
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 1
@@ -307,6 +494,17 @@ define i1 @PR42691_4(i32 %x) {
   ret i1 %c
 }
 
+define i1 @PR42691_4_logical(i32 %x) {
+; CHECK-LABEL: @PR42691_4_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 1
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %c1 = icmp uge i32 %x, 2147483648
+  %c2 = icmp eq i32 %x, 0
+  %c = select i1 %c1, i1 true, i1 %c2
+  ret i1 %c
+}
+
 define i1 @PR42691_5(i32 %x) {
 ; CHECK-LABEL: @PR42691_5(
 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], -1
@@ -319,6 +517,18 @@ define i1 @PR42691_5(i32 %x) {
   ret i1 %c
 }
 
+define i1 @PR42691_5_logical(i32 %x) {
+; CHECK-LABEL: @PR42691_5_logical(
+; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], -1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 2147483645
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %c1 = icmp slt i32 %x, 1
+  %c2 = icmp eq i32 %x, 2147483647
+  %c = select i1 %c1, i1 true, i1 %c2
+  ret i1 %c
+}
+
 define i1 @PR42691_6(i32 %x) {
 ; CHECK-LABEL: @PR42691_6(
 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], 2147483647
@@ -331,6 +541,18 @@ define i1 @PR42691_6(i32 %x) {
   ret i1 %c
 }
 
+define i1 @PR42691_6_logical(i32 %x) {
+; CHECK-LABEL: @PR42691_6_logical(
+; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], 2147483647
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 2147483645
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %c1 = icmp ult i32 %x, 2147483649
+  %c2 = icmp eq i32 %x, 4294967295
+  %c = select i1 %c1, i1 true, i1 %c2
+  ret i1 %c
+}
+
 define i1 @PR42691_7(i32 %x) {
 ; CHECK-LABEL: @PR42691_7(
 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -1
@@ -343,6 +565,18 @@ define i1 @PR42691_7(i32 %x) {
   ret i1 %c
 }
 
+define i1 @PR42691_7_logical(i32 %x) {
+; CHECK-LABEL: @PR42691_7_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -1
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 0
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %c1 = icmp uge i32 %x, 2147483649
+  %c2 = icmp eq i32 %x, 0
+  %c = select i1 %c1, i1 true, i1 %c2
+  ret i1 %c
+}
+
 define i1 @PR42691_8(i32 %x) {
 ; CHECK-LABEL: @PR42691_8(
 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], 2147483647
@@ -355,6 +589,18 @@ define i1 @PR42691_8(i32 %x) {
   ret i1 %c
 }
 
+define i1 @PR42691_8_logical(i32 %x) {
+; CHECK-LABEL: @PR42691_8_logical(
+; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], 2147483647
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], -2147483635
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %c1 = icmp slt i32 %x, 14
+  %c2 = icmp ne i32 %x, -2147483648
+  %c = select i1 %c1, i1 %c2, i1 false
+  ret i1 %c
+}
+
 define i1 @PR42691_9(i32 %x) {
 ; CHECK-LABEL: @PR42691_9(
 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], -14
@@ -367,6 +613,18 @@ define i1 @PR42691_9(i32 %x) {
   ret i1 %c
 }
 
+define i1 @PR42691_9_logical(i32 %x) {
+; CHECK-LABEL: @PR42691_9_logical(
+; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], -14
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], 2147483633
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %c1 = icmp sgt i32 %x, 13
+  %c2 = icmp ne i32 %x, 2147483647
+  %c = select i1 %c1, i1 %c2, i1 false
+  ret i1 %c
+}
+
 define i1 @PR42691_10(i32 %x) {
 ; CHECK-LABEL: @PR42691_10(
 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], -14
@@ -379,6 +637,18 @@ define i1 @PR42691_10(i32 %x) {
   ret i1 %c
 }
 
+define i1 @PR42691_10_logical(i32 %x) {
+; CHECK-LABEL: @PR42691_10_logical(
+; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], -14
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], -15
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %c1 = icmp ugt i32 %x, 13
+  %c2 = icmp ne i32 %x, 4294967295
+  %c = select i1 %c1, i1 %c2, i1 false
+  ret i1 %c
+}
+
 define i1 @substitute_constant_and_eq_eq(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_and_eq_eq(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
@@ -392,6 +662,19 @@ define i1 @substitute_constant_and_eq_eq(i8 %x, i8 %y) {
   ret i1 %r
 }
 
+define i1 @substitute_constant_and_eq_eq_logical(i8 %x, i8 %y) {
+; CHECK-LABEL: @substitute_constant_and_eq_eq_logical(
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 42
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C1]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %c1 = icmp eq i8 %x, 42
+  %c2 = icmp eq i8 %x, %y
+  %r = select i1 %c1, i1 %c2, i1 false
+  ret i1 %r
+}
+
 define i1 @substitute_constant_and_eq_eq_commute(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_and_eq_eq_commute(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
@@ -405,6 +688,19 @@ define i1 @substitute_constant_and_eq_eq_commute(i8 %x, i8 %y) {
   ret i1 %r
 }
 
+define i1 @substitute_constant_and_eq_eq_commute_logical(i8 %x, i8 %y) {
+; CHECK-LABEL: @substitute_constant_and_eq_eq_commute_logical(
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 42
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C1]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %c1 = icmp eq i8 %x, 42
+  %c2 = icmp eq i8 %x, %y
+  %r = select i1 %c2, i1 %c1, i1 false
+  ret i1 %r
+}
+
 define i1 @substitute_constant_and_eq_ugt_swap(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_and_eq_ugt_swap(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
@@ -418,6 +714,19 @@ define i1 @substitute_constant_and_eq_ugt_swap(i8 %x, i8 %y) {
   ret i1 %r
 }
 
+define i1 @substitute_constant_and_eq_ugt_swap_logical(i8 %x, i8 %y) {
+; CHECK-LABEL: @substitute_constant_and_eq_ugt_swap_logical(
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[Y:%.*]], 42
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C1]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %c1 = icmp eq i8 %x, 42
+  %c2 = icmp ugt i8 %y, %x
+  %r = select i1 %c2, i1 %c1, i1 false
+  ret i1 %r
+}
+
 define <2 x i1> @substitute_constant_and_eq_ne_vec(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @substitute_constant_and_eq_ne_vec(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 42, i8 97>
@@ -446,6 +755,21 @@ define i1 @substitute_constant_and_eq_sgt_use(i8 %x, i8 %y) {
   ret i1 %r
 }
 
+define i1 @substitute_constant_and_eq_sgt_use_logical(i8 %x, i8 %y) {
+; CHECK-LABEL: @substitute_constant_and_eq_sgt_use_logical(
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
+; CHECK-NEXT:    call void @use(i1 [[C1]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 42
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C1]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %c1 = icmp eq i8 %x, 42
+  call void @use(i1 %c1)
+  %c2 = icmp sgt i8 %x, %y
+  %r = select i1 %c2, i1 %c1, i1 false
+  ret i1 %r
+}
+
 ; Negative test - extra use
 
 define i1 @substitute_constant_and_eq_sgt_use2(i8 %x, i8 %y) {
@@ -463,6 +787,21 @@ define i1 @substitute_constant_and_eq_sgt_use2(i8 %x, i8 %y) {
   ret i1 %r
 }
 
+define i1 @substitute_constant_and_eq_sgt_use2_logical(i8 %x, i8 %y) {
+; CHECK-LABEL: @substitute_constant_and_eq_sgt_use2_logical(
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
+; CHECK-NEXT:    [[C2:%.*]] = icmp sgt i8 [[X]], [[Y:%.*]]
+; CHECK-NEXT:    call void @use(i1 [[C2]])
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[C2]], [[C1]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %c1 = icmp eq i8 %x, 42
+  %c2 = icmp sgt i8 %x, %y
+  call void @use(i1 %c2)
+  %r = select i1 %c2, i1 %c1, i1 false
+  ret i1 %r
+}
+
 ; Extra use does not prevent transform if the expression simplifies:
 ; X == MAX && X < Y --> false
 
@@ -479,6 +818,19 @@ define i1 @slt_and_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @slt_and_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @slt_and_max_logical(
+; CHECK-NEXT:    [[C2:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    call void @use(i1 [[C2]])
+; CHECK-NEXT:    ret i1 false
+;
+  %c1 = icmp eq i8 %x, 127
+  %c2 = icmp slt i8 %x, %y
+  call void @use(i1 %c2)
+  %r = select i1 %c2, i1 %c1, i1 false
+  ret i1 %r
+}
+
 ; Extra use does not prevent transform if the expression simplifies:
 ; X == MAX && X >= Y --> X == MAX
 
@@ -496,6 +848,20 @@ define i1 @sge_and_max(i8 %x, i8 %y)  {
   ret i1 %r
 }
 
+define i1 @sge_and_max_logical(i8 %x, i8 %y)  {
+; CHECK-LABEL: @sge_and_max_logical(
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 127
+; CHECK-NEXT:    [[C2:%.*]] = icmp sge i8 [[X]], [[Y:%.*]]
+; CHECK-NEXT:    call void @use(i1 [[C2]])
+; CHECK-NEXT:    ret i1 [[C1]]
+;
+  %c1 = icmp eq i8 %x, 127
+  %c2 = icmp sge i8 %x, %y
+  call void @use(i1 %c2)
+  %r = select i1 %c2, i1 %c1, i1 false
+  ret i1 %r
+}
+
 define i1 @substitute_constant_and_ne_ugt_swap(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_and_ne_ugt_swap(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
@@ -509,6 +875,19 @@ define i1 @substitute_constant_and_ne_ugt_swap(i8 %x, i8 %y) {
   ret i1 %r
 }
 
+define i1 @substitute_constant_and_ne_ugt_swap_logical(i8 %x, i8 %y) {
+; CHECK-LABEL: @substitute_constant_and_ne_ugt_swap_logical(
+; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
+; CHECK-NEXT:    [[C2:%.*]] = icmp ugt i8 [[Y:%.*]], [[X]]
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[C2]], [[C1]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %c1 = icmp ne i8 %x, 42
+  %c2 = icmp ugt i8 %y, %x
+  %r = select i1 %c2, i1 %c1, i1 false
+  ret i1 %r
+}
+
 define i1 @substitute_constant_or_ne_swap_sle(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_or_ne_swap_sle(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
@@ -522,6 +901,19 @@ define i1 @substitute_constant_or_ne_swap_sle(i8 %x, i8 %y) {
   ret i1 %r
 }
 
+define i1 @substitute_constant_or_ne_swap_sle_logical(i8 %x, i8 %y) {
+; CHECK-LABEL: @substitute_constant_or_ne_swap_sle_logical(
+; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 43
+; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[C1]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %c1 = icmp ne i8 %x, 42
+  %c2 = icmp sle i8 %y, %x
+  %r = select i1 %c1, i1 true, i1 %c2
+  ret i1 %r
+}
+
 define i1 @substitute_constant_or_ne_uge_commute(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_or_ne_uge_commute(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
@@ -535,6 +927,19 @@ define i1 @substitute_constant_or_ne_uge_commute(i8 %x, i8 %y) {
   ret i1 %r
 }
 
+define i1 @substitute_constant_or_ne_uge_commute_logical(i8 %x, i8 %y) {
+; CHECK-LABEL: @substitute_constant_or_ne_uge_commute_logical(
+; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i8 [[Y:%.*]], 43
+; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[C1]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %c1 = icmp ne i8 %x, 42
+  %c2 = icmp uge i8 %x, %y
+  %r = select i1 %c2, i1 true, i1 %c1
+  ret i1 %r
+}
+
 ; Negative test - not safe to substitute vector constant with undef element
 
 define <2 x i1> @substitute_constant_or_ne_slt_swap_vec(<2 x i8> %x, <2 x i8> %y) {
@@ -563,6 +968,19 @@ define i1 @substitute_constant_or_eq_swap_ne(i8 %x, i8 %y) {
   ret i1 %r
 }
 
+define i1 @substitute_constant_or_eq_swap_ne_logical(i8 %x, i8 %y) {
+; CHECK-LABEL: @substitute_constant_or_eq_swap_ne_logical(
+; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
+; CHECK-NEXT:    [[C2:%.*]] = icmp ne i8 [[Y:%.*]], [[X]]
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[C1]], [[C2]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %c1 = icmp eq i8 %x, 42
+  %c2 = icmp ne i8 %y, %x
+  %r = select i1 %c1, i1 true, i1 %c2
+  ret i1 %r
+}
+
 define i1 @substitute_constant_or_ne_sge_use(i8 %x, i8 %y) {
 ; CHECK-LABEL: @substitute_constant_or_ne_sge_use(
 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
@@ -578,6 +996,21 @@ define i1 @substitute_constant_or_ne_sge_use(i8 %x, i8 %y) {
   ret i1 %r
 }
 
+define i1 @substitute_constant_or_ne_sge_use_logical(i8 %x, i8 %y) {
+; CHECK-LABEL: @substitute_constant_or_ne_sge_use_logical(
+; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
+; CHECK-NEXT:    call void @use(i1 [[C1]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 43
+; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[C1]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %c1 = icmp ne i8 %x, 42
+  call void @use(i1 %c1)
+  %c2 = icmp sge i8 %x, %y
+  %r = select i1 %c2, i1 true, i1 %c1
+  ret i1 %r
+}
+
 ; Negative test - extra use
 
 define i1 @substitute_constant_or_ne_ule_use2(i8 %x, i8 %y) {
@@ -594,3 +1027,18 @@ define i1 @substitute_constant_or_ne_ule_use2(i8 %x, i8 %y) {
   %r = or i1 %c2, %c1
   ret i1 %r
 }
+
+define i1 @substitute_constant_or_ne_ule_use2_logical(i8 %x, i8 %y) {
+; CHECK-LABEL: @substitute_constant_or_ne_ule_use2_logical(
+; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
+; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[X]], [[Y:%.*]]
+; CHECK-NEXT:    call void @use(i1 [[C2]])
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[C2]], [[C1]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %c1 = icmp ne i8 %x, 42
+  %c2 = icmp ule i8 %x, %y
+  call void @use(i1 %c2)
+  %r = select i1 %c2, i1 true, i1 %c1
+  ret i1 %r
+}

diff  --git a/llvm/test/Transforms/InstCombine/and.ll b/llvm/test/Transforms/InstCombine/and.ll
index 020dbc483d9d..669cba88faba 100644
--- a/llvm/test/Transforms/InstCombine/and.ll
+++ b/llvm/test/Transforms/InstCombine/and.ll
@@ -30,6 +30,14 @@ define i1 @test3(i1 %A) {
   ret i1 %B
 }
 
+define i1 @test3_logical(i1 %A) {
+; CHECK-LABEL: @test3_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %B = select i1 %A, i1 false, i1 false
+  ret i1 %B
+}
+
 define i1 @test4(i1 %A) {
 ; CHECK-LABEL: @test4(
 ; CHECK-NEXT:    ret i1 [[A:%.*]]
@@ -38,6 +46,14 @@ define i1 @test4(i1 %A) {
   ret i1 %B
 }
 
+define i1 @test4_logical(i1 %A) {
+; CHECK-LABEL: @test4_logical(
+; CHECK-NEXT:    ret i1 [[A:%.*]]
+;
+  %B = select i1 %A, i1 true, i1 false
+  ret i1 %B
+}
+
 define i32 @test5(i32 %A) {
 ; CHECK-LABEL: @test5(
 ; CHECK-NEXT:    ret i32 [[A:%.*]]
@@ -54,6 +70,14 @@ define i1 @test6(i1 %A) {
   ret i1 %B
 }
 
+define i1 @test6_logical(i1 %A) {
+; CHECK-LABEL: @test6_logical(
+; CHECK-NEXT:    ret i1 [[A:%.*]]
+;
+  %B = select i1 %A, i1 %A, i1 false
+  ret i1 %B
+}
+
 ; A & ~A == 0
 define i32 @test7(i32 %A) {
 ; CHECK-LABEL: @test7(
@@ -135,6 +159,18 @@ define i1 @test12(i32 %A, i32 %B) {
   ret i1 %D
 }
 
+define i1 @test12_logical(i32 %A, i32 %B) {
+; CHECK-LABEL: @test12_logical(
+; CHECK-NEXT:    [[C1:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[C1]]
+;
+  %C1 = icmp ult i32 %A, %B
+  %C2 = icmp ule i32 %A, %B
+  ; (A < B) & (A <= B) === (A < B)
+  %D = select i1 %C1, i1 %C2, i1 false
+  ret i1 %D
+}
+
 define i1 @test13(i32 %A, i32 %B) {
 ; CHECK-LABEL: @test13(
 ; CHECK-NEXT:    ret i1 false
@@ -146,6 +182,17 @@ define i1 @test13(i32 %A, i32 %B) {
   ret i1 %D
 }
 
+define i1 @test13_logical(i32 %A, i32 %B) {
+; CHECK-LABEL: @test13_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %C1 = icmp ult i32 %A, %B
+  %C2 = icmp ugt i32 %A, %B
+  ; (A < B) & (A > B) === false
+  %D = select i1 %C1, i1 %C2, i1 false
+  ret i1 %D
+}
+
 define i1 @test14(i8 %A) {
 ; CHECK-LABEL: @test14(
 ; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 [[A:%.*]], 0
@@ -249,6 +296,17 @@ define i1 @test23(i32 %A) {
   ret i1 %D
 }
 
+define i1 @test23_logical(i32 %A) {
+; CHECK-LABEL: @test23_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[A:%.*]], 2
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %B = icmp sgt i32 %A, 1
+  %C = icmp sle i32 %A, 2
+  %D = select i1 %B, i1 %C, i1 false
+  ret i1 %D
+}
+
 ; FIXME: Vectors should fold too.
 define <2 x i1> @test23vec(<2 x i32> %A) {
 ; CHECK-LABEL: @test23vec(
@@ -275,6 +333,18 @@ define i1 @test24(i32 %A) {
   ret i1 %D
 }
 
+define i1 @test24_logical(i32 %A) {
+; CHECK-LABEL: @test24_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], 2
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %B = icmp sgt i32 %A, 1
+  %C = icmp ne i32 %A, 2
+  ;; A > 2
+  %D = select i1 %B, i1 %C, i1 false
+  ret i1 %D
+}
+
 define i1 @test25(i32 %A) {
 ; CHECK-LABEL: @test25(
 ; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -50
@@ -287,6 +357,18 @@ define i1 @test25(i32 %A) {
   ret i1 %D
 }
 
+define i1 @test25_logical(i32 %A) {
+; CHECK-LABEL: @test25_logical(
+; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -50
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[A_OFF]], 50
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %B = icmp sge i32 %A, 50
+  %C = icmp slt i32 %A, 100
+  %D = select i1 %B, i1 %C, i1 false
+  ret i1 %D
+}
+
 ; FIXME: Vectors should fold too.
 define <2 x i1> @test25vec(<2 x i32> %A) {
 ; CHECK-LABEL: @test25vec(
@@ -758,6 +840,21 @@ define i1 @and_orn_cmp_1(i32 %a, i32 %b, i32 %c) {
   ret i1 %and
 }
 
+define i1 @and_orn_cmp_1_logical(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: @and_orn_cmp_1_logical(
+; CHECK-NEXT:    [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X]], [[Y]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %x = icmp sgt i32 %a, %b
+  %x_inv = icmp sle i32 %a, %b
+  %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
+  %or = select i1 %y, i1 true, i1 %x_inv
+  %and = select i1 %x, i1 %or, i1 false
+  ret i1 %and
+}
+
 ; Commute the 'and':
 ; ((Y | ~X) & X) -> (X & Y), where 'not' is an inverted cmp
 
@@ -794,6 +891,21 @@ define i1 @and_orn_cmp_3(i72 %a, i72 %b, i72 %c) {
   ret i1 %and
 }
 
+define i1 @and_orn_cmp_3_logical(i72 %a, i72 %b, i72 %c) {
+; CHECK-LABEL: @and_orn_cmp_3_logical(
+; CHECK-NEXT:    [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X]], [[Y]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %x = icmp ugt i72 %a, %b
+  %x_inv = icmp ule i72 %a, %b
+  %y = icmp ugt i72 %c, 42      ; thwart complexity-based ordering
+  %or = select i1 %x_inv, i1 true, i1 %y
+  %and = select i1 %x, i1 %or, i1 false
+  ret i1 %and
+}
+
 ; Commute the 'and':
 ; ((~X | Y) & X) -> (X & Y), where 'not' is an inverted cmp
 
@@ -830,6 +942,21 @@ define i1 @andn_or_cmp_1(i37 %a, i37 %b, i37 %c) {
   ret i1 %and
 }
 
+define i1 @andn_or_cmp_1_logical(i37 %a, i37 %b, i37 %c) {
+; CHECK-LABEL: @andn_or_cmp_1_logical(
+; CHECK-NEXT:    [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X_INV]], [[Y]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %x = icmp sgt i37 %a, %b
+  %x_inv = icmp sle i37 %a, %b
+  %y = icmp ugt i37 %c, 42      ; thwart complexity-based ordering
+  %or = select i1 %y, i1 true, i1 %x
+  %and = select i1 %x_inv, i1 %or, i1 false
+  ret i1 %and
+}
+
 ; Commute the 'and':
 ; ((Y | X) & ~X) -> (~X & Y), where 'not' is an inverted cmp
 
@@ -848,6 +975,21 @@ define i1 @andn_or_cmp_2(i16 %a, i16 %b, i16 %c) {
   ret i1 %and
 }
 
+define i1 @andn_or_cmp_2_logical(i16 %a, i16 %b, i16 %c) {
+; CHECK-LABEL: @andn_or_cmp_2_logical(
+; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[Y]], [[X_INV]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %x = icmp sge i16 %a, %b
+  %x_inv = icmp slt i16 %a, %b
+  %y = icmp ugt i16 %c, 42      ; thwart complexity-based ordering
+  %or = select i1 %y, i1 true, i1 %x
+  %and = select i1 %or, i1 %x_inv, i1 false
+  ret i1 %and
+}
+
 ; Commute the 'or':
 ; (~X & (X | Y)) -> (~X & Y), where 'not' is an inverted cmp
 
@@ -884,6 +1026,21 @@ define i1 @andn_or_cmp_4(i32 %a, i32 %b, i32 %c) {
   ret i1 %and
 }
 
+define i1 @andn_or_cmp_4_logical(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: @andn_or_cmp_4_logical(
+; CHECK-NEXT:    [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[Y]], [[X_INV]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %x = icmp eq i32 %a, %b
+  %x_inv = icmp ne i32 %a, %b
+  %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
+  %or = select i1 %x, i1 true, i1 %y
+  %and = select i1 %or, i1 %x_inv, i1 false
+  ret i1 %and
+}
+
 define i32 @lowbitmask_casted_shift(i8 %x) {
 ; CHECK-LABEL: @lowbitmask_casted_shift(
 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32

diff  --git a/llvm/test/Transforms/InstCombine/and2.ll b/llvm/test/Transforms/InstCombine/and2.ll
index 47b0d2d6245e..6b12e26ab5f3 100644
--- a/llvm/test/Transforms/InstCombine/and2.ll
+++ b/llvm/test/Transforms/InstCombine/and2.ll
@@ -11,6 +11,16 @@ define i1 @test2(i1 %X, i1 %Y) {
   ret i1 %b
 }
 
+define i1 @test2_logical(i1 %X, i1 %Y) {
+; CHECK-LABEL: @test2_logical(
+; CHECK-NEXT:    [[A:%.*]] = and i1 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[A]]
+;
+  %a = select i1 %X, i1 %Y, i1 false
+  %b = select i1 %a, i1 %X, i1 false
+  ret i1 %b
+}
+
 define i32 @test3(i32 %X, i32 %Y) {
 ; CHECK-LABEL: @test3(
 ; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
@@ -34,6 +44,19 @@ define i1 @test7(i32 %i, i1 %b) {
   ret i1 %and2
 }
 
+define i1 @test7_logical(i32 %i, i1 %b) {
+; CHECK-LABEL: @test7_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[I:%.*]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp1 = icmp slt i32 %i, 1
+  %cmp2 = icmp sgt i32 %i, -1
+  %and1 = select i1 %cmp1, i1 %b, i1 false
+  %and2 = select i1 %and1, i1 %cmp2, i1 false
+  ret i1 %and2
+}
+
 define i1 @test8(i32 %i) {
 ; CHECK-LABEL: @test8(
 ; CHECK-NEXT:    [[I_OFF:%.*]] = add i32 [[I:%.*]], -1
@@ -46,6 +69,18 @@ define i1 @test8(i32 %i) {
   ret i1 %cond
 }
 
+define i1 @test8_logical(i32 %i) {
+; CHECK-LABEL: @test8_logical(
+; CHECK-NEXT:    [[I_OFF:%.*]] = add i32 [[I:%.*]], -1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[I_OFF]], 13
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp1 = icmp ne i32 %i, 0
+  %cmp2 = icmp ult i32 %i, 14
+  %cond = select i1 %cmp1, i1 %cmp2, i1 false
+  ret i1 %cond
+}
+
 ; FIXME: Vectors should fold too.
 define <2 x i1> @test8vec(<2 x i32> %i) {
 ; CHECK-LABEL: @test8vec(

diff  --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll
index a988eea89445..f46ffbec2ce6 100644
--- a/llvm/test/Transforms/InstCombine/assume.ll
+++ b/llvm/test/Transforms/InstCombine/assume.ll
@@ -69,6 +69,19 @@ define i32 @can1(i1 %a, i1 %b, i1 %c) {
   ret i32 5
 }
 
+define i32 @can1_logical(i1 %a, i1 %b, i1 %c) {
+; CHECK-LABEL: @can1_logical(
+; CHECK-NEXT:    call void @llvm.assume(i1 [[A:%.*]])
+; CHECK-NEXT:    call void @llvm.assume(i1 [[B:%.*]])
+; CHECK-NEXT:    call void @llvm.assume(i1 [[C:%.*]])
+; CHECK-NEXT:    ret i32 5
+;
+  %and1 = select i1 %a, i1 %b, i1 false
+  %and  = select i1 %and1, i1 %c, i1 false
+  tail call void @llvm.assume(i1 %and)
+  ret i32 5
+}
+
 define i32 @can2(i1 %a, i1 %b, i1 %c) {
 ; CHECK-LABEL: @can2(
 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[A:%.*]], true
@@ -83,6 +96,20 @@ define i32 @can2(i1 %a, i1 %b, i1 %c) {
   ret i32 5
 }
 
+define i32 @can2_logical(i1 %a, i1 %b, i1 %c) {
+; CHECK-LABEL: @can2_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[A:%.*]], true
+; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP1]])
+; CHECK-NEXT:    [[TMP2:%.*]] = xor i1 [[B:%.*]], true
+; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP2]])
+; CHECK-NEXT:    ret i32 5
+;
+  %v = select i1 %a, i1 true, i1 %b
+  %w = xor i1 %v, 1
+  tail call void @llvm.assume(i1 %w)
+  ret i32 5
+}
+
 define i32 @bar1(i32 %a) #0 {
 ; CHECK-LABEL: @bar1(
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 7
@@ -595,6 +622,43 @@ exit:
   unreachable
 }
 
+define i32 @unreachable_assume_logical(i32 %x, i32 %y) {
+; CHECK-LABEL: @unreachable_assume_logical(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP0:%.*]] = icmp sgt i32 [[X:%.*]], 1
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[Y:%.*]], 1
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT:    tail call void @llvm.assume(i1 [[OR]])
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[X]], 1
+; CHECK-NEXT:    br i1 [[CMP2]], label [[IF:%.*]], label [[EXIT:%.*]]
+; CHECK:       if:
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[Y]], -2
+; CHECK-NEXT:    [[CMP3:%.*]] = icmp ne i32 [[A]], 104
+; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP3]])
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    unreachable
+;
+entry:
+  %cmp0 = icmp sgt i32 %x, 1
+  %cmp1 = icmp eq i32 %y, 1
+  %or = select i1 %cmp0, i1 true, i1 %cmp1
+  tail call void @llvm.assume(i1 %or)
+  %cmp2 = icmp eq i32 %x, 1
+  br i1 %cmp2, label %if, label %exit
+
+if:
+  %a = and i32 %y, -2
+  %cmp3 = icmp ne i32 %a, 104
+  tail call void @llvm.assume(i1 %cmp3)
+  br label %exit
+
+exit:
+  %cmp4 = icmp eq i32 %x, 2
+  tail call void @llvm.assume(i1 %cmp4)
+  unreachable
+}
+
 define i32 @unreachable_assumes_and_store(i32 %x, i32 %y, i32* %p) {
 ; CHECK-LABEL: @unreachable_assumes_and_store(
 ; CHECK-NEXT:  entry:
@@ -635,6 +699,46 @@ exit:
   unreachable
 }
 
+define i32 @unreachable_assumes_and_store_logical(i32 %x, i32 %y, i32* %p) {
+; CHECK-LABEL: @unreachable_assumes_and_store_logical(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP0:%.*]] = icmp sgt i32 [[X:%.*]], 1
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[Y:%.*]], 1
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT:    tail call void @llvm.assume(i1 [[OR]])
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[X]], 1
+; CHECK-NEXT:    br i1 [[CMP2]], label [[IF:%.*]], label [[EXIT:%.*]]
+; CHECK:       if:
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[Y]], -2
+; CHECK-NEXT:    [[CMP3:%.*]] = icmp ne i32 [[A]], 104
+; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP3]])
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    unreachable
+;
+entry:
+  %cmp0 = icmp sgt i32 %x, 1
+  %cmp1 = icmp eq i32 %y, 1
+  %or = select i1 %cmp0, i1 true, i1 %cmp1
+  tail call void @llvm.assume(i1 %or)
+  %cmp2 = icmp eq i32 %x, 1
+  br i1 %cmp2, label %if, label %exit
+
+if:
+  %a = and i32 %y, -2
+  %cmp3 = icmp ne i32 %a, 104
+  tail call void @llvm.assume(i1 %cmp3)
+  br label %exit
+
+exit:
+  %cmp4 = icmp eq i32 %x, 2
+  tail call void @llvm.assume(i1 %cmp4)
+  %cmp5 = icmp ugt i32 %y, 42
+  tail call void @llvm.assume(i1 %cmp5)
+  store i32 %x, i32* %p
+  unreachable
+}
+
 declare void @llvm.dbg.value(metadata, metadata, metadata)
 
 !llvm.dbg.cu = !{!0}

diff  --git a/llvm/test/Transforms/InstCombine/bit-checks.ll b/llvm/test/Transforms/InstCombine/bit-checks.ll
index 1ecd305e807d..28464c41ad49 100644
--- a/llvm/test/Transforms/InstCombine/bit-checks.ll
+++ b/llvm/test/Transforms/InstCombine/bit-checks.ll
@@ -3,7 +3,7 @@
 
 define i32 @main1(i32 %argc) {
 ; CHECK-LABEL: @main1(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, 3
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 3
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 3
 ; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 2, i32 1
 ; CHECK-NEXT:    ret i32 [[RETVAL_0]]
@@ -17,11 +17,27 @@ define i32 @main1(i32 %argc) {
   ret i32 %retval.0
 }
 
+define i32 @main1_logical(i32 %argc) {
+; CHECK-LABEL: @main1_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 3
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 3
+; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 2, i32 1
+; CHECK-NEXT:    ret i32 [[RETVAL_0]]
+;
+  %and = and i32 %argc, 1
+  %tobool = icmp ne i32 %and, 0
+  %and2 = and i32 %argc, 2
+  %tobool3 = icmp ne i32 %and2, 0
+  %or.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %retval.0 = select i1 %or.cond, i32 2, i32 1
+  ret i32 %retval.0
+}
+
 define i32 @main2(i32 %argc) {
 ; CHECK-LABEL: @main2(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, 3
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp eq i32 [[TMP1]], 3
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 3
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 3
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, 1
@@ -33,6 +49,22 @@ define i32 @main2(i32 %argc) {
   ret i32 %storemerge
 }
 
+define i32 @main2_logical(i32 %argc) {
+; CHECK-LABEL: @main2_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 3
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 3
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, 1
+  %tobool = icmp eq i32 %and, 0
+  %and2 = and i32 %argc, 2
+  %tobool3 = icmp eq i32 %and2, 0
+  %or.cond = select i1 %tobool, i1 true, i1 %tobool3
+  %storemerge = select i1 %or.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 ; tests to check combining (icmp eq (A & B), C) & (icmp eq (A & D), E)
 ; tests to check if (icmp eq (A & B), 0) is treated like (icmp eq (A & B), B)
 ; if B is a single bit constant
@@ -40,9 +72,9 @@ define i32 @main2(i32 %argc) {
 ; (icmp eq (A & B), 0) & (icmp eq (A & D), 0) -> (icmp eq (A & (B|D)), 0)
 define i32 @main3(i32 %argc) {
 ; CHECK-LABEL: @main3(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, 55
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP1]], 0
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 55
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP2]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, 7
@@ -54,11 +86,27 @@ define i32 @main3(i32 %argc) {
   ret i32 %storemerge
 }
 
+define i32 @main3_logical(i32 %argc) {
+; CHECK-LABEL: @main3_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 55
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP2]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, 7
+  %tobool = icmp eq i32 %and, 0
+  %and2 = and i32 %argc, 48
+  %tobool3 = icmp eq i32 %and2, 0
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 define i32 @main3b(i32 %argc) {
 ; CHECK-LABEL: @main3b(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, 23
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP1]], 0
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 23
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP2]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, 7
@@ -70,12 +118,28 @@ define i32 @main3b(i32 %argc) {
   ret i32 %storemerge
 }
 
+define i32 @main3b_logical(i32 %argc) {
+; CHECK-LABEL: @main3b_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 23
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP2]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, 7
+  %tobool = icmp eq i32 %and, 0
+  %and2 = and i32 %argc, 16
+  %tobool3 = icmp ne i32 %and2, 16
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 define i32 @main3e_like(i32 %argc, i32 %argc2, i32 %argc3) {
 ; CHECK-LABEL: @main3e_like(
-; CHECK-NEXT:    [[TMP1:%.*]] = or i32 %argc2, %argc3
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], %argc
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP2]], 0
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, %argc2
@@ -87,12 +151,29 @@ define i32 @main3e_like(i32 %argc, i32 %argc2, i32 %argc3) {
   ret i32 %storemerge
 }
 
+define i32 @main3e_like_logical(i32 %argc, i32 %argc2, i32 %argc3) {
+; CHECK-LABEL: @main3e_like_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, %argc2
+  %tobool = icmp eq i32 %and, 0
+  %and2 = and i32 %argc, %argc3
+  %tobool3 = icmp eq i32 %and2, 0
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 ; (icmp ne (A & B), 0) | (icmp ne (A & D), 0) -> (icmp ne (A & (B|D)), 0)
 define i32 @main3c(i32 %argc) {
 ; CHECK-LABEL: @main3c(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, 55
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 55
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, 7
@@ -104,11 +185,27 @@ define i32 @main3c(i32 %argc) {
   ret i32 %storemerge
 }
 
+define i32 @main3c_logical(i32 %argc) {
+; CHECK-LABEL: @main3c_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 55
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, 7
+  %tobool = icmp ne i32 %and, 0
+  %and2 = and i32 %argc, 48
+  %tobool3 = icmp ne i32 %and2, 0
+  %or.cond = select i1 %tobool, i1 true, i1 %tobool3
+  %storemerge = select i1 %or.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 define i32 @main3d(i32 %argc) {
 ; CHECK-LABEL: @main3d(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, 23
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 23
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, 7
@@ -120,12 +217,28 @@ define i32 @main3d(i32 %argc) {
   ret i32 %storemerge
 }
 
+define i32 @main3d_logical(i32 %argc) {
+; CHECK-LABEL: @main3d_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 23
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, 7
+  %tobool = icmp ne i32 %and, 0
+  %and2 = and i32 %argc, 16
+  %tobool3 = icmp eq i32 %and2, 16
+  %or.cond = select i1 %tobool, i1 true, i1 %tobool3
+  %storemerge = select i1 %or.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 define i32 @main3f_like(i32 %argc, i32 %argc2, i32 %argc3) {
 ; CHECK-LABEL: @main3f_like(
-; CHECK-NEXT:    [[TMP1:%.*]] = or i32 %argc2, %argc3
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], %argc
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp eq i32 [[TMP2]], 0
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, %argc2
@@ -137,12 +250,29 @@ define i32 @main3f_like(i32 %argc, i32 %argc2, i32 %argc3) {
   ret i32 %storemerge
 }
 
+define i32 @main3f_like_logical(i32 %argc, i32 %argc2, i32 %argc3) {
+; CHECK-LABEL: @main3f_like_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, %argc2
+  %tobool = icmp ne i32 %and, 0
+  %and2 = and i32 %argc, %argc3
+  %tobool3 = icmp ne i32 %and2, 0
+  %or.cond = select i1 %tobool, i1 true, i1 %tobool3
+  %storemerge = select i1 %or.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 ; (icmp eq (A & B), B) & (icmp eq (A & D), D) -> (icmp eq (A & (B|D)), (B|D))
 define i32 @main4(i32 %argc) {
 ; CHECK-LABEL: @main4(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, 55
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP1]], 55
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 55
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 55
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP2]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, 7
@@ -154,11 +284,27 @@ define i32 @main4(i32 %argc) {
   ret i32 %storemerge
 }
 
+define i32 @main4_logical(i32 %argc) {
+; CHECK-LABEL: @main4_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 55
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 55
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP2]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, 7
+  %tobool = icmp eq i32 %and, 7
+  %and2 = and i32 %argc, 48
+  %tobool3 = icmp eq i32 %and2, 48
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 define i32 @main4b(i32 %argc) {
 ; CHECK-LABEL: @main4b(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, 23
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP1]], 23
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 23
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 23
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP2]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, 7
@@ -170,12 +316,28 @@ define i32 @main4b(i32 %argc) {
   ret i32 %storemerge
 }
 
+define i32 @main4b_logical(i32 %argc) {
+; CHECK-LABEL: @main4b_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 23
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 23
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP2]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, 7
+  %tobool = icmp eq i32 %and, 7
+  %and2 = and i32 %argc, 16
+  %tobool3 = icmp ne i32 %and2, 0
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 define i32 @main4e_like(i32 %argc, i32 %argc2, i32 %argc3) {
 ; CHECK-LABEL: @main4e_like(
-; CHECK-NEXT:    [[TMP1:%.*]] = or i32 %argc2, %argc3
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], %argc
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, %argc2
@@ -187,12 +349,29 @@ define i32 @main4e_like(i32 %argc, i32 %argc2, i32 %argc3) {
   ret i32 %storemerge
 }
 
+define i32 @main4e_like_logical(i32 %argc, i32 %argc2, i32 %argc3) {
+; CHECK-LABEL: @main4e_like_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, %argc2
+  %tobool = icmp eq i32 %and, %argc2
+  %and2 = and i32 %argc, %argc3
+  %tobool3 = icmp eq i32 %and2, %argc3
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 ; (icmp ne (A & B), B) | (icmp ne (A & D), D) -> (icmp ne (A & (B|D)), (B|D))
 define i32 @main4c(i32 %argc) {
 ; CHECK-LABEL: @main4c(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, 55
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp eq i32 [[TMP1]], 55
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 55
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 55
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, 7
@@ -204,11 +383,27 @@ define i32 @main4c(i32 %argc) {
   ret i32 %storemerge
 }
 
+define i32 @main4c_logical(i32 %argc) {
+; CHECK-LABEL: @main4c_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 55
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 55
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, 7
+  %tobool = icmp ne i32 %and, 7
+  %and2 = and i32 %argc, 48
+  %tobool3 = icmp ne i32 %and2, 48
+  %or.cond = select i1 %tobool, i1 true, i1 %tobool3
+  %storemerge = select i1 %or.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 define i32 @main4d(i32 %argc) {
 ; CHECK-LABEL: @main4d(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, 23
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp eq i32 [[TMP1]], 23
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 23
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 23
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, 7
@@ -220,12 +415,28 @@ define i32 @main4d(i32 %argc) {
   ret i32 %storemerge
 }
 
+define i32 @main4d_logical(i32 %argc) {
+; CHECK-LABEL: @main4d_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 23
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 23
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, 7
+  %tobool = icmp ne i32 %and, 7
+  %and2 = and i32 %argc, 16
+  %tobool3 = icmp eq i32 %and2, 0
+  %or.cond = select i1 %tobool, i1 true, i1 %tobool3
+  %storemerge = select i1 %or.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 define i32 @main4f_like(i32 %argc, i32 %argc2, i32 %argc3) {
 ; CHECK-LABEL: @main4f_like(
-; CHECK-NEXT:    [[TMP1:%.*]] = or i32 %argc2, %argc3
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], %argc
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp eq i32 [[TMP2]], [[TMP1]]
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, %argc2
@@ -237,13 +448,30 @@ define i32 @main4f_like(i32 %argc, i32 %argc2, i32 %argc3) {
   ret i32 %storemerge
 }
 
+define i32 @main4f_like_logical(i32 %argc, i32 %argc2, i32 %argc3) {
+; CHECK-LABEL: @main4f_like_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, %argc2
+  %tobool = icmp ne i32 %and, %argc2
+  %and2 = and i32 %argc, %argc3
+  %tobool3 = icmp ne i32 %and2, %argc3
+  %or.cond = select i1 %tobool, i1 true, i1 %tobool3
+  %storemerge = select i1 %or.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 ; (icmp eq (A & B), A) & (icmp eq (A & D), A) -> (icmp eq (A & (B&D)), A)
 define i32 @main5_like(i32 %argc, i32 %argc2) {
 ; CHECK-LABEL: @main5_like(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, %argc2
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], [[ARGC2:%.*]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 7
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP2]], 7
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 7
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, 7
@@ -255,12 +483,29 @@ define i32 @main5_like(i32 %argc, i32 %argc2) {
   ret i32 %storemerge
 }
 
+define i32 @main5_like_logical(i32 %argc, i32 %argc2) {
+; CHECK-LABEL: @main5_like_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], [[ARGC2:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 7
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 7
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, 7
+  %tobool = icmp eq i32 %and, 7
+  %and2 = and i32 %argc2, 7
+  %tobool3 = icmp eq i32 %and2, 7
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 define i32 @main5e_like(i32 %argc, i32 %argc2, i32 %argc3) {
 ; CHECK-LABEL: @main5e_like(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc2, %argc3
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], %argc
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP2]], %argc
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[ARGC]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, %argc2
@@ -272,13 +517,30 @@ define i32 @main5e_like(i32 %argc, i32 %argc2, i32 %argc3) {
   ret i32 %storemerge
 }
 
+define i32 @main5e_like_logical(i32 %argc, i32 %argc2, i32 %argc3) {
+; CHECK-LABEL: @main5e_like_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[ARGC]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, %argc2
+  %tobool = icmp eq i32 %and, %argc
+  %and2 = and i32 %argc, %argc3
+  %tobool3 = icmp eq i32 %and2, %argc
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 ; (icmp ne (A & B), A) | (icmp ne (A & D), A) -> (icmp ne (A & (B&D)), A)
 define i32 @main5c_like(i32 %argc, i32 %argc2) {
 ; CHECK-LABEL: @main5c_like(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, %argc2
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], [[ARGC2:%.*]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 7
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp eq i32 [[TMP2]], 7
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP2]], 7
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, 7
@@ -290,12 +552,29 @@ define i32 @main5c_like(i32 %argc, i32 %argc2) {
   ret i32 %storemerge
 }
 
+define i32 @main5c_like_logical(i32 %argc, i32 %argc2) {
+; CHECK-LABEL: @main5c_like_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], [[ARGC2:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 7
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP2]], 7
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, 7
+  %tobool = icmp ne i32 %and, 7
+  %and2 = and i32 %argc2, 7
+  %tobool3 = icmp ne i32 %and2, 7
+  %or.cond = select i1 %tobool, i1 true, i1 %tobool3
+  %storemerge = select i1 %or.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 define i32 @main5f_like(i32 %argc, i32 %argc2, i32 %argc3) {
 ; CHECK-LABEL: @main5f_like(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc2, %argc3
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], %argc
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp eq i32 [[TMP2]], %argc
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP2]], [[ARGC]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, %argc2
@@ -307,13 +586,30 @@ define i32 @main5f_like(i32 %argc, i32 %argc2, i32 %argc3) {
   ret i32 %storemerge
 }
 
+define i32 @main5f_like_logical(i32 %argc, i32 %argc2, i32 %argc3) {
+; CHECK-LABEL: @main5f_like_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP2]], [[ARGC]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, %argc2
+  %tobool = icmp ne i32 %and, %argc
+  %and2 = and i32 %argc, %argc3
+  %tobool3 = icmp ne i32 %and2, %argc
+  %or.cond = select i1 %tobool, i1 true, i1 %tobool3
+  %storemerge = select i1 %or.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 ; (icmp eq (A & B), C) & (icmp eq (A & D), E) -> (icmp eq (A & (B|D)), (C|E))
 ; if B, C, D, E are constant, and it's possible
 define i32 @main6(i32 %argc) {
 ; CHECK-LABEL: @main6(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, 55
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP1]], 19
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 55
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 19
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP2]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, 7
@@ -325,11 +621,27 @@ define i32 @main6(i32 %argc) {
   ret i32 %storemerge
 }
 
+define i32 @main6_logical(i32 %argc) {
+; CHECK-LABEL: @main6_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 55
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 19
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP2]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, 7
+  %tobool = icmp eq i32 %and, 3
+  %and2 = and i32 %argc, 48
+  %tobool3 = icmp eq i32 %and2, 16
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 define i32 @main6b(i32 %argc) {
 ; CHECK-LABEL: @main6b(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, 23
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP1]], 19
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 23
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 19
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP2]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, 7
@@ -341,13 +653,29 @@ define i32 @main6b(i32 %argc) {
   ret i32 %storemerge
 }
 
+define i32 @main6b_logical(i32 %argc) {
+; CHECK-LABEL: @main6b_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 23
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 19
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP2]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, 7
+  %tobool = icmp eq i32 %and, 3
+  %and2 = and i32 %argc, 16
+  %tobool3 = icmp ne i32 %and2, 0
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 ; (icmp ne (A & B), C) | (icmp ne (A & D), E) -> (icmp ne (A & (B|D)), (C|E))
 ; if B, C, D, E are constant, and it's possible
 define i32 @main6c(i32 %argc) {
 ; CHECK-LABEL: @main6c(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, 55
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp eq i32 [[TMP1]], 19
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 55
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 19
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, 7
@@ -359,11 +687,27 @@ define i32 @main6c(i32 %argc) {
   ret i32 %storemerge
 }
 
+define i32 @main6c_logical(i32 %argc) {
+; CHECK-LABEL: @main6c_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 55
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 19
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, 7
+  %tobool = icmp ne i32 %and, 3
+  %and2 = and i32 %argc, 48
+  %tobool3 = icmp ne i32 %and2, 16
+  %or.cond = select i1 %tobool, i1 true, i1 %tobool3
+  %storemerge = select i1 %or.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 define i32 @main6d(i32 %argc) {
 ; CHECK-LABEL: @main6d(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %argc, 23
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp eq i32 [[TMP1]], 19
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 23
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 19
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and = and i32 %argc, 7
@@ -375,14 +719,30 @@ define i32 @main6d(i32 %argc) {
   ret i32 %storemerge
 }
 
+define i32 @main6d_logical(i32 %argc) {
+; CHECK-LABEL: @main6d_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 23
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 19
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[DOTNOT]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and = and i32 %argc, 7
+  %tobool = icmp ne i32 %and, 3
+  %and2 = and i32 %argc, 16
+  %tobool3 = icmp eq i32 %and2, 0
+  %or.cond = select i1 %tobool, i1 true, i1 %tobool3
+  %storemerge = select i1 %or.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 ; test parameter permutations
 ; (B & A) == B & (D & A) == D
 define i32 @main7a(i32 %argc, i32 %argc2, i32 %argc3) {
 ; CHECK-LABEL: @main7a(
-; CHECK-NEXT:    [[TMP1:%.*]] = or i32 %argc2, %argc3
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], %argc
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and1 = and i32 %argc2, %argc
@@ -394,13 +754,30 @@ define i32 @main7a(i32 %argc, i32 %argc2, i32 %argc3) {
   ret i32 %storemerge
 }
 
+define i32 @main7a_logical(i32 %argc, i32 %argc2, i32 %argc3) {
+; CHECK-LABEL: @main7a_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and1 = and i32 %argc2, %argc
+  %tobool = icmp eq i32 %and1, %argc2
+  %and2 = and i32 %argc3, %argc
+  %tobool3 = icmp eq i32 %and2, %argc3
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 ; B == (A & B) & D == (A & D)
 define i32 @main7b(i32 %argc, i32 %argc2, i32 %argc3) {
 ; CHECK-LABEL: @main7b(
-; CHECK-NEXT:    [[TMP1:%.*]] = or i32 %argc2, %argc3
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], %argc
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and1 = and i32 %argc, %argc2
@@ -412,13 +789,30 @@ define i32 @main7b(i32 %argc, i32 %argc2, i32 %argc3) {
   ret i32 %storemerge
 }
 
+define i32 @main7b_logical(i32 %argc, i32 %argc2, i32 %argc3) {
+; CHECK-LABEL: @main7b_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and1 = and i32 %argc, %argc2
+  %tobool = icmp eq i32 %argc2, %and1
+  %and2 = and i32 %argc, %argc3
+  %tobool3 = icmp eq i32 %argc3, %and2
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 ; B == (B & A) & D == (D & A)
 define i32 @main7c(i32 %argc, i32 %argc2, i32 %argc3) {
 ; CHECK-LABEL: @main7c(
-; CHECK-NEXT:    [[TMP1:%.*]] = or i32 %argc2, %argc3
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], %argc
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %and1 = and i32 %argc2, %argc
@@ -430,15 +824,32 @@ define i32 @main7c(i32 %argc, i32 %argc2, i32 %argc3) {
   ret i32 %storemerge
 }
 
+define i32 @main7c_logical(i32 %argc, i32 %argc2, i32 %argc3) {
+; CHECK-LABEL: @main7c_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARGC2:%.*]], [[ARGC3:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %and1 = and i32 %argc2, %argc
+  %tobool = icmp eq i32 %argc2, %and1
+  %and2 = and i32 %argc3, %argc
+  %tobool3 = icmp eq i32 %argc3, %and2
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 ; (A & (B & C)) == (B & C) & (A & (D & E)) == (D & E)
 define i32 @main7d(i32 %argc, i32 %argc2, i32 %argc3, i32 %argc4, i32 %argc5) {
 ; CHECK-LABEL: @main7d(
-; CHECK-NEXT:    [[BC:%.*]] = and i32 %argc2, %argc4
-; CHECK-NEXT:    [[DE:%.*]] = and i32 %argc3, %argc5
+; CHECK-NEXT:    [[BC:%.*]] = and i32 [[ARGC2:%.*]], [[ARGC4:%.*]]
+; CHECK-NEXT:    [[DE:%.*]] = and i32 [[ARGC3:%.*]], [[ARGC5:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[BC]], [[DE]]
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], %argc
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %bc = and i32 %argc2, %argc4
@@ -452,15 +863,36 @@ define i32 @main7d(i32 %argc, i32 %argc2, i32 %argc3, i32 %argc4, i32 %argc5) {
   ret i32 %storemerge
 }
 
+define i32 @main7d_logical(i32 %argc, i32 %argc2, i32 %argc3, i32 %argc4, i32 %argc5) {
+; CHECK-LABEL: @main7d_logical(
+; CHECK-NEXT:    [[BC:%.*]] = and i32 [[ARGC2:%.*]], [[ARGC4:%.*]]
+; CHECK-NEXT:    [[DE:%.*]] = and i32 [[ARGC3:%.*]], [[ARGC5:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[BC]], [[DE]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %bc = and i32 %argc2, %argc4
+  %de = and i32 %argc3, %argc5
+  %and1 = and i32 %argc, %bc
+  %tobool = icmp eq i32 %and1, %bc
+  %and2 = and i32 %argc, %de
+  %tobool3 = icmp eq i32 %and2, %de
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 ; ((B & C) & A) == (B & C) & ((D & E) & A) == (D & E)
 define i32 @main7e(i32 %argc, i32 %argc2, i32 %argc3, i32 %argc4, i32 %argc5) {
 ; CHECK-LABEL: @main7e(
-; CHECK-NEXT:    [[BC:%.*]] = and i32 %argc2, %argc4
-; CHECK-NEXT:    [[DE:%.*]] = and i32 %argc3, %argc5
+; CHECK-NEXT:    [[BC:%.*]] = and i32 [[ARGC2:%.*]], [[ARGC4:%.*]]
+; CHECK-NEXT:    [[DE:%.*]] = and i32 [[ARGC3:%.*]], [[ARGC5:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[BC]], [[DE]]
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], %argc
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %bc = and i32 %argc2, %argc4
@@ -474,15 +906,36 @@ define i32 @main7e(i32 %argc, i32 %argc2, i32 %argc3, i32 %argc4, i32 %argc5) {
   ret i32 %storemerge
 }
 
+define i32 @main7e_logical(i32 %argc, i32 %argc2, i32 %argc3, i32 %argc4, i32 %argc5) {
+; CHECK-LABEL: @main7e_logical(
+; CHECK-NEXT:    [[BC:%.*]] = and i32 [[ARGC2:%.*]], [[ARGC4:%.*]]
+; CHECK-NEXT:    [[DE:%.*]] = and i32 [[ARGC3:%.*]], [[ARGC5:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[BC]], [[DE]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %bc = and i32 %argc2, %argc4
+  %de = and i32 %argc3, %argc5
+  %and1 = and i32 %bc, %argc
+  %tobool = icmp eq i32 %and1, %bc
+  %and2 = and i32 %de, %argc
+  %tobool3 = icmp eq i32 %and2, %de
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 ; (B & C) == (A & (B & C)) & (D & E) == (A & (D & E))
 define i32 @main7f(i32 %argc, i32 %argc2, i32 %argc3, i32 %argc4, i32 %argc5) {
 ; CHECK-LABEL: @main7f(
-; CHECK-NEXT:    [[BC:%.*]] = and i32 %argc2, %argc4
-; CHECK-NEXT:    [[DE:%.*]] = and i32 %argc3, %argc5
+; CHECK-NEXT:    [[BC:%.*]] = and i32 [[ARGC2:%.*]], [[ARGC4:%.*]]
+; CHECK-NEXT:    [[DE:%.*]] = and i32 [[ARGC3:%.*]], [[ARGC5:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[BC]], [[DE]]
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], %argc
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %bc = and i32 %argc2, %argc4
@@ -496,15 +949,36 @@ define i32 @main7f(i32 %argc, i32 %argc2, i32 %argc3, i32 %argc4, i32 %argc5) {
   ret i32 %storemerge
 }
 
+define i32 @main7f_logical(i32 %argc, i32 %argc2, i32 %argc3, i32 %argc4, i32 %argc5) {
+; CHECK-LABEL: @main7f_logical(
+; CHECK-NEXT:    [[BC:%.*]] = and i32 [[ARGC2:%.*]], [[ARGC4:%.*]]
+; CHECK-NEXT:    [[DE:%.*]] = and i32 [[ARGC3:%.*]], [[ARGC5:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[BC]], [[DE]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %bc = and i32 %argc2, %argc4
+  %de = and i32 %argc3, %argc5
+  %and1 = and i32 %argc, %bc
+  %tobool = icmp eq i32 %bc, %and1
+  %and2 = and i32 %argc, %de
+  %tobool3 = icmp eq i32 %de, %and2
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 ; (B & C) == ((B & C) & A) & (D & E) == ((D & E) & A)
 define i32 @main7g(i32 %argc, i32 %argc2, i32 %argc3, i32 %argc4, i32 %argc5) {
 ; CHECK-LABEL: @main7g(
-; CHECK-NEXT:    [[BC:%.*]] = and i32 %argc2, %argc4
-; CHECK-NEXT:    [[DE:%.*]] = and i32 %argc3, %argc5
+; CHECK-NEXT:    [[BC:%.*]] = and i32 [[ARGC2:%.*]], [[ARGC4:%.*]]
+; CHECK-NEXT:    [[DE:%.*]] = and i32 [[ARGC3:%.*]], [[ARGC5:%.*]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[BC]], [[DE]]
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], %argc
-; CHECK-NEXT:    [[NOT_:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
-; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[NOT_]] to i32
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
 ; CHECK-NEXT:    ret i32 [[STOREMERGE]]
 ;
   %bc = and i32 %argc2, %argc4
@@ -518,11 +992,32 @@ define i32 @main7g(i32 %argc, i32 %argc2, i32 %argc3, i32 %argc4, i32 %argc5) {
   ret i32 %storemerge
 }
 
+define i32 @main7g_logical(i32 %argc, i32 %argc2, i32 %argc3, i32 %argc4, i32 %argc5) {
+; CHECK-LABEL: @main7g_logical(
+; CHECK-NEXT:    [[BC:%.*]] = and i32 [[ARGC2:%.*]], [[ARGC4:%.*]]
+; CHECK-NEXT:    [[DE:%.*]] = and i32 [[ARGC3:%.*]], [[ARGC5:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[BC]], [[DE]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[ARGC:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[STOREMERGE:%.*]] = zext i1 [[TMP3]] to i32
+; CHECK-NEXT:    ret i32 [[STOREMERGE]]
+;
+  %bc = and i32 %argc2, %argc4
+  %de = and i32 %argc3, %argc5
+  %and1 = and i32 %bc, %argc
+  %tobool = icmp eq i32 %bc, %and1
+  %and2 = and i32 %de, %argc
+  %tobool3 = icmp eq i32 %de, %and2
+  %and.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %storemerge = select i1 %and.cond, i32 0, i32 1
+  ret i32 %storemerge
+}
+
 define i32 @main8(i32 %argc) {
 ; CHECK-LABEL: @main8(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 192
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 1, i32 2
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[DOTNOT]], i32 1, i32 2
 ; CHECK-NEXT:    ret i32 [[RETVAL_0]]
 ;
   %and = and i32 %argc, 64
@@ -534,6 +1029,22 @@ define i32 @main8(i32 %argc) {
   ret i32 %retval.0
 }
 
+define i32 @main8_logical(i32 %argc) {
+; CHECK-LABEL: @main8_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 192
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[DOTNOT]], i32 1, i32 2
+; CHECK-NEXT:    ret i32 [[RETVAL_0]]
+;
+  %and = and i32 %argc, 64
+  %tobool = icmp ne i32 %and, 0
+  %trunc2 = trunc i32 %argc to i8
+  %tobool3 = icmp slt i8 %trunc2, 0
+  %or.cond = select i1 %tobool, i1 true, i1 %tobool3
+  %retval.0 = select i1 %or.cond, i32 2, i32 1
+  ret i32 %retval.0
+}
+
 define i32 @main9(i32 %argc) {
 ; CHECK-LABEL: @main9(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 192
@@ -550,6 +1061,22 @@ define i32 @main9(i32 %argc) {
   ret i32 %retval.0
 }
 
+define i32 @main9_logical(i32 %argc) {
+; CHECK-LABEL: @main9_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 192
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 192
+; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 2, i32 1
+; CHECK-NEXT:    ret i32 [[RETVAL_0]]
+;
+  %and = and i32 %argc, 64
+  %tobool = icmp ne i32 %and, 0
+  %trunc2 = trunc i32 %argc to i8
+  %tobool3 = icmp slt i8 %trunc2, 0
+  %or.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %retval.0 = select i1 %or.cond, i32 2, i32 1
+  ret i32 %retval.0
+}
+
 define i32 @main10(i32 %argc) {
 ; CHECK-LABEL: @main10(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 192
@@ -566,11 +1093,27 @@ define i32 @main10(i32 %argc) {
   ret i32 %retval.0
 }
 
+define i32 @main10_logical(i32 %argc) {
+; CHECK-LABEL: @main10_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 192
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 2, i32 1
+; CHECK-NEXT:    ret i32 [[RETVAL_0]]
+;
+  %and = and i32 %argc, 64
+  %tobool = icmp eq i32 %and, 0
+  %trunc2 = trunc i32 %argc to i8
+  %tobool3 = icmp sge i8 %trunc2, 0
+  %or.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %retval.0 = select i1 %or.cond, i32 2, i32 1
+  ret i32 %retval.0
+}
+
 define i32 @main11(i32 %argc) {
 ; CHECK-LABEL: @main11(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 192
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 192
-; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 1, i32 2
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 192
+; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[DOTNOT]], i32 1, i32 2
 ; CHECK-NEXT:    ret i32 [[RETVAL_0]]
 ;
   %and = and i32 %argc, 64
@@ -582,11 +1125,27 @@ define i32 @main11(i32 %argc) {
   ret i32 %retval.0
 }
 
+define i32 @main11_logical(i32 %argc) {
+; CHECK-LABEL: @main11_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 192
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 192
+; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[DOTNOT]], i32 1, i32 2
+; CHECK-NEXT:    ret i32 [[RETVAL_0]]
+;
+  %and = and i32 %argc, 64
+  %tobool = icmp eq i32 %and, 0
+  %trunc2 = trunc i32 %argc to i8
+  %tobool3 = icmp sge i8 %trunc2, 0
+  %or.cond = select i1 %tobool, i1 true, i1 %tobool3
+  %retval.0 = select i1 %or.cond, i32 2, i32 1
+  ret i32 %retval.0
+}
+
 define i32 @main12(i32 %argc) {
 ; CHECK-LABEL: @main12(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 32896
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 1, i32 2
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[DOTNOT]], i32 1, i32 2
 ; CHECK-NEXT:    ret i32 [[RETVAL_0]]
 ;
   %trunc = trunc i32 %argc to i16
@@ -598,6 +1157,22 @@ define i32 @main12(i32 %argc) {
   ret i32 %retval.0
 }
 
+define i32 @main12_logical(i32 %argc) {
+; CHECK-LABEL: @main12_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 32896
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[DOTNOT]], i32 1, i32 2
+; CHECK-NEXT:    ret i32 [[RETVAL_0]]
+;
+  %trunc = trunc i32 %argc to i16
+  %tobool = icmp slt i16 %trunc, 0
+  %trunc2 = trunc i32 %argc to i8
+  %tobool3 = icmp slt i8 %trunc2, 0
+  %or.cond = select i1 %tobool, i1 true, i1 %tobool3
+  %retval.0 = select i1 %or.cond, i32 2, i32 1
+  ret i32 %retval.0
+}
+
 define i32 @main13(i32 %argc) {
 ; CHECK-LABEL: @main13(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 32896
@@ -614,6 +1189,22 @@ define i32 @main13(i32 %argc) {
   ret i32 %retval.0
 }
 
+define i32 @main13_logical(i32 %argc) {
+; CHECK-LABEL: @main13_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 32896
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 32896
+; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 2, i32 1
+; CHECK-NEXT:    ret i32 [[RETVAL_0]]
+;
+  %trunc = trunc i32 %argc to i16
+  %tobool = icmp slt i16 %trunc, 0
+  %trunc2 = trunc i32 %argc to i8
+  %tobool3 = icmp slt i8 %trunc2, 0
+  %or.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %retval.0 = select i1 %or.cond, i32 2, i32 1
+  ret i32 %retval.0
+}
+
 define i32 @main14(i32 %argc) {
 ; CHECK-LABEL: @main14(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 32896
@@ -630,11 +1221,27 @@ define i32 @main14(i32 %argc) {
   ret i32 %retval.0
 }
 
+define i32 @main14_logical(i32 %argc) {
+; CHECK-LABEL: @main14_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 32896
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 2, i32 1
+; CHECK-NEXT:    ret i32 [[RETVAL_0]]
+;
+  %trunc = trunc i32 %argc to i16
+  %tobool = icmp sge i16 %trunc, 0
+  %trunc2 = trunc i32 %argc to i8
+  %tobool3 = icmp sge i8 %trunc2, 0
+  %or.cond = select i1 %tobool, i1 %tobool3, i1 false
+  %retval.0 = select i1 %or.cond, i32 2, i32 1
+  ret i32 %retval.0
+}
+
 define i32 @main15(i32 %argc) {
 ; CHECK-LABEL: @main15(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 32896
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 32896
-; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[TMP2]], i32 1, i32 2
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 32896
+; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[DOTNOT]], i32 1, i32 2
 ; CHECK-NEXT:    ret i32 [[RETVAL_0]]
 ;
   %trunc = trunc i32 %argc to i16
@@ -645,3 +1252,19 @@ define i32 @main15(i32 %argc) {
   %retval.0 = select i1 %or.cond, i32 2, i32 1
   ret i32 %retval.0
 }
+
+define i32 @main15_logical(i32 %argc) {
+; CHECK-LABEL: @main15_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARGC:%.*]], 32896
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 32896
+; CHECK-NEXT:    [[RETVAL_0:%.*]] = select i1 [[DOTNOT]], i32 1, i32 2
+; CHECK-NEXT:    ret i32 [[RETVAL_0]]
+;
+  %trunc = trunc i32 %argc to i16
+  %tobool = icmp sge i16 %trunc, 0
+  %trunc2 = trunc i32 %argc to i8
+  %tobool3 = icmp sge i8 %trunc2, 0
+  %or.cond = select i1 %tobool, i1 true, i1 %tobool3
+  %retval.0 = select i1 %or.cond, i32 2, i32 1
+  ret i32 %retval.0
+}

diff  --git a/llvm/test/Transforms/InstCombine/canonicalize-clamp-with-select-of-constant-threshold-pattern.ll b/llvm/test/Transforms/InstCombine/canonicalize-clamp-with-select-of-constant-threshold-pattern.ll
index 0156c9071a64..593e50abdb12 100644
--- a/llvm/test/Transforms/InstCombine/canonicalize-clamp-with-select-of-constant-threshold-pattern.ll
+++ b/llvm/test/Transforms/InstCombine/canonicalize-clamp-with-select-of-constant-threshold-pattern.ll
@@ -20,6 +20,22 @@ define i32 @t0_select_cond_and_v0(i32 %X) {
   %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
   ret i32 %R
 }
+
+define i32 @t0_select_cond_and_v0_logical(i32 %X) {
+; CHECK-LABEL: @t0_select_cond_and_v0_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 -32768
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 32767
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 32767
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %dont_need_to_clamp_positive = icmp sle i32 %X, 32767
+  %dont_need_to_clamp_negative = icmp sge i32 %X, -32768
+  %clamp_limit = select i1 %dont_need_to_clamp_positive, i32 -32768, i32 32767
+  %dont_need_to_clamp = select i1 %dont_need_to_clamp_positive, i1 %dont_need_to_clamp_negative, i1 false
+  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
+  ret i32 %R
+}
 define i32 @t1_select_cond_and_v1(i32 %X) {
 ; CHECK-LABEL: @t1_select_cond_and_v1(
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
@@ -36,6 +52,22 @@ define i32 @t1_select_cond_and_v1(i32 %X) {
   ret i32 %R
 }
 
+define i32 @t1_select_cond_and_v1_logical(i32 %X) {
+; CHECK-LABEL: @t1_select_cond_and_v1_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 -32768
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 32767
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 32767
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %dont_need_to_clamp_positive = icmp sle i32 %X, 32767
+  %dont_need_to_clamp_negative = icmp sge i32 %X, -32768
+  %clamp_limit = select i1 %dont_need_to_clamp_negative, i32 32767, i32 -32768
+  %dont_need_to_clamp = select i1 %dont_need_to_clamp_positive, i1 %dont_need_to_clamp_negative, i1 false
+  %R = select i1 %dont_need_to_clamp, i32 %X, i32 %clamp_limit
+  ret i32 %R
+}
+
 ;-------------------------------------------------------------------------------
 
 define i32 @t2_select_cond_or_v0(i32 %X) {
@@ -53,6 +85,22 @@ define i32 @t2_select_cond_or_v0(i32 %X) {
   %R = select i1 %need_to_clamp, i32 %clamp_limit, i32 %X
   ret i32 %R
 }
+
+define i32 @t2_select_cond_or_v0_logical(i32 %X) {
+; CHECK-LABEL: @t2_select_cond_or_v0_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 -32768
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 32767
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 32767
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %need_to_clamp_positive = icmp sgt i32 %X, 32767
+  %need_to_clamp_negative = icmp slt i32 %X, -32768
+  %clamp_limit = select i1 %need_to_clamp_positive, i32 32767, i32 -32768
+  %need_to_clamp = select i1 %need_to_clamp_positive, i1 true, i1 %need_to_clamp_negative
+  %R = select i1 %need_to_clamp, i32 %clamp_limit, i32 %X
+  ret i32 %R
+}
 define i32 @t3_select_cond_or_v1(i32 %X) {
 ; CHECK-LABEL: @t3_select_cond_or_v1(
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
@@ -69,12 +117,28 @@ define i32 @t3_select_cond_or_v1(i32 %X) {
   ret i32 %R
 }
 
+define i32 @t3_select_cond_or_v1_logical(i32 %X) {
+; CHECK-LABEL: @t3_select_cond_or_v1_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 -32768
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 32767
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 32767
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %need_to_clamp_positive = icmp sgt i32 %X, 32767
+  %need_to_clamp_negative = icmp slt i32 %X, -32768
+  %clamp_limit = select i1 %need_to_clamp_negative, i32 -32768, i32 32767
+  %need_to_clamp = select i1 %need_to_clamp_positive, i1 true, i1 %need_to_clamp_negative
+  %R = select i1 %need_to_clamp, i32 %clamp_limit, i32 %X
+  ret i32 %R
+}
+
 ;-------------------------------------------------------------------------------
 
 define i32 @t4_select_cond_xor_v0(i32 %X) {
 ; CHECK-LABEL: @t4_select_cond_xor_v0(
-; CHECK-NEXT:    [[DOTINV1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
-; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV1]], i32 [[X]], i32 -32768
+; CHECK-NEXT:    [[DOTINV:%.*]] = icmp sgt i32 [[X:%.*]], -32768
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV]], i32 [[X]], i32 -32768
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 32767
 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP1]], i32 32767
 ; CHECK-NEXT:    ret i32 [[R]]
@@ -88,8 +152,8 @@ define i32 @t4_select_cond_xor_v0(i32 %X) {
 }
 define i32 @t4_select_cond_xor_v1(i32 %X) {
 ; CHECK-LABEL: @t4_select_cond_xor_v1(
-; CHECK-NEXT:    [[DOTINV1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
-; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV1]], i32 [[X]], i32 -32768
+; CHECK-NEXT:    [[DOTINV:%.*]] = icmp sgt i32 [[X:%.*]], -32768
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV]], i32 [[X]], i32 -32768
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 32767
 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP1]], i32 32767
 ; CHECK-NEXT:    ret i32 [[R]]
@@ -104,8 +168,8 @@ define i32 @t4_select_cond_xor_v1(i32 %X) {
 
 define i32 @t5_select_cond_xor_v2(i32 %X) {
 ; CHECK-LABEL: @t5_select_cond_xor_v2(
-; CHECK-NEXT:    [[DOTINV1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
-; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV1]], i32 [[X]], i32 -32768
+; CHECK-NEXT:    [[DOTINV:%.*]] = icmp sgt i32 [[X:%.*]], -32768
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV]], i32 [[X]], i32 -32768
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 32767
 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP1]], i32 32767
 ; CHECK-NEXT:    ret i32 [[R]]
@@ -119,8 +183,8 @@ define i32 @t5_select_cond_xor_v2(i32 %X) {
 }
 define i32 @t5_select_cond_xor_v3(i32 %X) {
 ; CHECK-LABEL: @t5_select_cond_xor_v3(
-; CHECK-NEXT:    [[DOTINV1:%.*]] = icmp sgt i32 [[X:%.*]], -32768
-; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV1]], i32 [[X]], i32 -32768
+; CHECK-NEXT:    [[DOTINV:%.*]] = icmp sgt i32 [[X:%.*]], -32768
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV]], i32 [[X]], i32 -32768
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 32767
 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[TMP1]], i32 32767
 ; CHECK-NEXT:    ret i32 [[R]]

diff  --git a/llvm/test/Transforms/InstCombine/demorgan.ll b/llvm/test/Transforms/InstCombine/demorgan.ll
index 465621a24a54..809c43d1a09d 100644
--- a/llvm/test/Transforms/InstCombine/demorgan.ll
+++ b/llvm/test/Transforms/InstCombine/demorgan.ll
@@ -471,6 +471,22 @@ define i32 @PR28476(i32 %x, i32 %y) {
   ret i32 %cond
 }
 
+define i32 @PR28476_logical(i32 %x, i32 %y) {
+; CHECK-LABEL: @PR28476_logical(
+; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq i32 [[X:%.*]], 0
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[Y:%.*]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT:    [[COND:%.*]] = zext i1 [[TMP1]] to i32
+; CHECK-NEXT:    ret i32 [[COND]]
+;
+  %cmp0 = icmp ne i32 %x, 0
+  %cmp1 = icmp ne i32 %y, 0
+  %and = select i1 %cmp0, i1 %cmp1, i1 false
+  %zext = zext i1 %and to i32
+  %cond = xor i32 %zext, 1
+  ret i32 %cond
+}
+
 ; ~(~(a | b) | (a & b)) --> (a | b) & ~(a & b) -> a ^ b
 
 define i32 @demorgan_plus_and_to_xor(i32 %a, i32 %b) {

diff  --git a/llvm/test/Transforms/InstCombine/dont-distribute-phi.ll b/llvm/test/Transforms/InstCombine/dont-distribute-phi.ll
index bc7ddacbed16..98d91c9b048f 100644
--- a/llvm/test/Transforms/InstCombine/dont-distribute-phi.ll
+++ b/llvm/test/Transforms/InstCombine/dont-distribute-phi.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -instcombine -S | FileCheck %s
 ;
 ; This test ensures that InstCombine does not distribute And over Xor
@@ -5,6 +6,21 @@
 
 define zeroext i1 @foo(i32 %arg) {
 ; CHECK-LABEL: @foo(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[ARG:%.*]], 37
+; CHECK-NEXT:    br i1 [[CMP1]], label [[BB_THEN:%.*]], label [[BB_ELSE:%.*]]
+; CHECK:       bb_then:
+; CHECK-NEXT:    call void @bar()
+; CHECK-NEXT:    br label [[BB_EXIT:%.*]]
+; CHECK:       bb_else:
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[ARG]], 17
+; CHECK-NEXT:    br label [[BB_EXIT]]
+; CHECK:       bb_exit:
+; CHECK-NEXT:    [[PHI1:%.*]] = phi i1 [ [[CMP2]], [[BB_ELSE]] ], [ undef, [[BB_THEN]] ]
+; CHECK-NEXT:    [[XOR1:%.*]] = xor i1 [[CMP1]], true
+; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[PHI1]], [[XOR1]]
+; CHECK-NEXT:    ret i1 [[AND1]]
+;
 
 entry:
   %cmp1 = icmp eq i32 %arg, 37
@@ -18,15 +34,47 @@ bb_else:
   %cmp2 = icmp slt i32 %arg, 17
   br label %bb_exit
 
+bb_exit:
+  %phi1 = phi i1 [ %cmp2, %bb_else ], [ undef, %bb_then ]
+  %xor1 = xor i1 %cmp1, true
+  %and1 = and i1 %phi1, %xor1
+  ret i1 %and1
+}
+
+define zeroext i1 @foo_logical(i32 %arg) {
+; CHECK-LABEL: @foo_logical(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[ARG:%.*]], 37
+; CHECK-NEXT:    br i1 [[CMP1]], label [[BB_THEN:%.*]], label [[BB_ELSE:%.*]]
+; CHECK:       bb_then:
+; CHECK-NEXT:    call void @bar()
+; CHECK-NEXT:    br label [[BB_EXIT:%.*]]
+; CHECK:       bb_else:
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[ARG]], 17
+; CHECK-NEXT:    br label [[BB_EXIT]]
 ; CHECK:       bb_exit:
-; CHECK-NEXT:    [[PHI1:%.*]] = phi i1 [ [[CMP2:%.*]], [[BB_ELSE:%.*]] ], [ undef, [[BB_THEN:%.*]] ]
-; CHECK-NEXT:    [[XOR1:%.*]] = xor i1 [[CMP1:%.*]], true
+; CHECK-NEXT:    [[PHI1:%.*]] = phi i1 [ [[CMP2]], [[BB_ELSE]] ], [ undef, [[BB_THEN]] ]
+; CHECK-NEXT:    [[XOR1:%.*]] = xor i1 [[CMP1]], true
 ; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[PHI1]], [[XOR1]]
 ; CHECK-NEXT:    ret i1 [[AND1]]
+;
+
+entry:
+  %cmp1 = icmp eq i32 %arg, 37
+  br i1 %cmp1, label %bb_then, label %bb_else
+
+bb_then:
+  call void @bar()
+  br label %bb_exit
+
+bb_else:
+  %cmp2 = icmp slt i32 %arg, 17
+  br label %bb_exit
+
 bb_exit:
   %phi1 = phi i1 [ %cmp2, %bb_else ], [ undef, %bb_then ]
   %xor1 = xor i1 %cmp1, true
-  %and1 = and i1 %phi1, %xor1
+  %and1 = select i1 %phi1, i1 %xor1, i1 false
   ret i1 %and1
 }
 

diff  --git a/llvm/test/Transforms/InstCombine/fold-bin-operand.ll b/llvm/test/Transforms/InstCombine/fold-bin-operand.ll
index fc0c13a5f1a7..db3e7f3afb96 100644
--- a/llvm/test/Transforms/InstCombine/fold-bin-operand.ll
+++ b/llvm/test/Transforms/InstCombine/fold-bin-operand.ll
@@ -10,6 +10,14 @@ define i1 @f(i1 %x) {
   ret i1 %b
 }
 
+define i1 @f_logical(i1 %x) {
+; CHECK-LABEL: @f_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %b = select i1 %x, i1 icmp eq (i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 2 to i8*)), i1 false
+  ret i1 %b
+}
+
 define i32 @g(i32 %x) {
 ; CHECK-LABEL: @g(
 ; CHECK-NEXT:    ret i32 [[X:%.*]]

diff  --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index 1a1ec2e2024d..2546ec387003 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -74,3 +74,15 @@ define void @or_select_multipleuses(i32 %x, i1 %y) {
   call void @use_i32_i1(i32 %a, i1 %b)
   ret void
 }
+
+define void @or_select_multipleuses_logical(i32 %x, i1 %y) {
+; CHECK-LABEL: @or_select_multipleuses_logical(
+; CHECK-NEXT:    call void @use_i32_i1(i32 32, i1 [[Y:%.*]])
+; CHECK-NEXT:    ret void
+;
+  %f = freeze i1 undef
+  %a = select i1 %f, i32 %x, i32 32 ; prefers %f to be false
+  %b = select i1 %f, i1 true, i1 %y ; prefers %f to be true
+  call void @use_i32_i1(i32 %a, i1 %b)
+  ret void
+}

diff  --git a/llvm/test/Transforms/InstCombine/icmp-custom-dl.ll b/llvm/test/Transforms/InstCombine/icmp-custom-dl.ll
index 09a3b2b5ff4f..6e76525bad35 100644
--- a/llvm/test/Transforms/InstCombine/icmp-custom-dl.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-custom-dl.ll
@@ -199,6 +199,24 @@ define i1 @icmp_and_ashr_multiuse(i32 %X) {
   ret i1 %and3
 }
 
+define i1 @icmp_and_ashr_multiuse_logical(i32 %X) {
+; CHECK-LABEL: @icmp_and_ashr_multiuse_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
+; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
+; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
+; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
+; CHECK-NEXT:    ret i1 [[AND3]]
+;
+  %shr = ashr i32 %X, 4
+  %and = and i32 %shr, 15
+  %and2 = and i32 %shr, 31 ; second use of the shift
+  %tobool = icmp ne i32 %and, 14
+  %tobool2 = icmp ne i32 %and2, 27
+  %and3 = select i1 %tobool, i1 %tobool2, i1 false
+  ret i1 %and3
+}
+
 define i1 @icmp_lshr_and_overshift(i8 %X) {
 ; CHECK-LABEL: @icmp_lshr_and_overshift(
 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ugt i8 [[X:%.*]], 31

diff  --git a/llvm/test/Transforms/InstCombine/icmp-logical.ll b/llvm/test/Transforms/InstCombine/icmp-logical.ll
index b5327df5e8e3..cc23b114bd01 100644
--- a/llvm/test/Transforms/InstCombine/icmp-logical.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-logical.ll
@@ -15,6 +15,20 @@ define i1 @masked_and_notallzeroes(i32 %A) {
   ret i1 %res
 }
 
+define i1 @masked_and_notallzeroes_logical(i32 %A) {
+; CHECK-LABEL: @masked_and_notallzeroes_logical(
+; CHECK-NEXT:    [[MASK1:%.*]] = and i32 [[A:%.*]], 7
+; CHECK-NEXT:    [[TST1:%.*]] = icmp ne i32 [[MASK1]], 0
+; CHECK-NEXT:    ret i1 [[TST1]]
+;
+  %mask1 = and i32 %A, 7
+  %tst1 = icmp ne i32 %mask1, 0
+  %mask2 = and i32 %A, 39
+  %tst2 = icmp ne i32 %mask2, 0
+  %res = select i1 %tst1, i1 %tst2, i1 false
+  ret i1 %res
+}
+
 define i1 @masked_or_allzeroes(i32 %A) {
 ; CHECK-LABEL: @masked_or_allzeroes(
 ; CHECK-NEXT:    [[MASK1:%.*]] = and i32 [[A:%.*]], 7
@@ -29,6 +43,20 @@ define i1 @masked_or_allzeroes(i32 %A) {
   ret i1 %res
 }
 
+define i1 @masked_or_allzeroes_logical(i32 %A) {
+; CHECK-LABEL: @masked_or_allzeroes_logical(
+; CHECK-NEXT:    [[MASK1:%.*]] = and i32 [[A:%.*]], 7
+; CHECK-NEXT:    [[TST1:%.*]] = icmp eq i32 [[MASK1]], 0
+; CHECK-NEXT:    ret i1 [[TST1]]
+;
+  %mask1 = and i32 %A, 7
+  %tst1 = icmp eq i32 %mask1, 0
+  %mask2 = and i32 %A, 39
+  %tst2 = icmp eq i32 %mask2, 0
+  %res = select i1 %tst1, i1 true, i1 %tst2
+  ret i1 %res
+}
+
 define i1 @masked_and_notallones(i32 %A) {
 ; CHECK-LABEL: @masked_and_notallones(
 ; CHECK-NEXT:    [[MASK1:%.*]] = and i32 [[A:%.*]], 7
@@ -43,6 +71,20 @@ define i1 @masked_and_notallones(i32 %A) {
   ret i1 %res
 }
 
+define i1 @masked_and_notallones_logical(i32 %A) {
+; CHECK-LABEL: @masked_and_notallones_logical(
+; CHECK-NEXT:    [[MASK1:%.*]] = and i32 [[A:%.*]], 7
+; CHECK-NEXT:    [[TST1:%.*]] = icmp ne i32 [[MASK1]], 7
+; CHECK-NEXT:    ret i1 [[TST1]]
+;
+  %mask1 = and i32 %A, 7
+  %tst1 = icmp ne i32 %mask1, 7
+  %mask2 = and i32 %A, 39
+  %tst2 = icmp ne i32 %mask2, 39
+  %res = select i1 %tst1, i1 %tst2, i1 false
+  ret i1 %res
+}
+
 define i1 @masked_or_allones(i32 %A) {
 ; CHECK-LABEL: @masked_or_allones(
 ; CHECK-NEXT:    [[MASK1:%.*]] = and i32 [[A:%.*]], 7
@@ -57,6 +99,20 @@ define i1 @masked_or_allones(i32 %A) {
   ret i1 %res
 }
 
+define i1 @masked_or_allones_logical(i32 %A) {
+; CHECK-LABEL: @masked_or_allones_logical(
+; CHECK-NEXT:    [[MASK1:%.*]] = and i32 [[A:%.*]], 7
+; CHECK-NEXT:    [[TST1:%.*]] = icmp eq i32 [[MASK1]], 7
+; CHECK-NEXT:    ret i1 [[TST1]]
+;
+  %mask1 = and i32 %A, 7
+  %tst1 = icmp eq i32 %mask1, 7
+  %mask2 = and i32 %A, 39
+  %tst2 = icmp eq i32 %mask2, 39
+  %res = select i1 %tst1, i1 true, i1 %tst2
+  ret i1 %res
+}
+
 define i1 @masked_and_notA(i32 %A) {
 ; CHECK-LABEL: @masked_and_notA(
 ; CHECK-NEXT:    [[MASK2:%.*]] = and i32 [[A:%.*]], 78
@@ -71,6 +127,20 @@ define i1 @masked_and_notA(i32 %A) {
   ret i1 %res
 }
 
+define i1 @masked_and_notA_logical(i32 %A) {
+; CHECK-LABEL: @masked_and_notA_logical(
+; CHECK-NEXT:    [[MASK2:%.*]] = and i32 [[A:%.*]], 78
+; CHECK-NEXT:    [[TST2:%.*]] = icmp ne i32 [[MASK2]], [[A]]
+; CHECK-NEXT:    ret i1 [[TST2]]
+;
+  %mask1 = and i32 %A, 14
+  %tst1 = icmp ne i32 %mask1, %A
+  %mask2 = and i32 %A, 78
+  %tst2 = icmp ne i32 %mask2, %A
+  %res = select i1 %tst1, i1 %tst2, i1 false
+  ret i1 %res
+}
+
 define i1 @masked_and_notA_slightly_optimized(i32 %A) {
 ; CHECK-LABEL: @masked_and_notA_slightly_optimized(
 ; CHECK-NEXT:    [[T0:%.*]] = icmp ugt i32 [[A:%.*]], 7
@@ -86,6 +156,21 @@ define i1 @masked_and_notA_slightly_optimized(i32 %A) {
   ret i1 %res
 }
 
+define i1 @masked_and_notA_slightly_optimized_logical(i32 %A) {
+; CHECK-LABEL: @masked_and_notA_slightly_optimized_logical(
+; CHECK-NEXT:    [[T0:%.*]] = icmp ugt i32 [[A:%.*]], 7
+; CHECK-NEXT:    [[MASK2:%.*]] = and i32 [[A]], 39
+; CHECK-NEXT:    [[TST2:%.*]] = icmp ne i32 [[MASK2]], [[A]]
+; CHECK-NEXT:    [[RES:%.*]] = and i1 [[T0]], [[TST2]]
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %t0 = icmp uge i32 %A, 8
+  %mask2 = and i32 %A, 39
+  %tst2 = icmp ne i32 %mask2, %A
+  %res = select i1 %t0, i1 %tst2, i1 false
+  ret i1 %res
+}
+
 define i1 @masked_or_A(i32 %A) {
 ; CHECK-LABEL: @masked_or_A(
 ; CHECK-NEXT:    [[MASK2:%.*]] = and i32 [[A:%.*]], 78
@@ -100,6 +185,20 @@ define i1 @masked_or_A(i32 %A) {
   ret i1 %res
 }
 
+define i1 @masked_or_A_logical(i32 %A) {
+; CHECK-LABEL: @masked_or_A_logical(
+; CHECK-NEXT:    [[MASK2:%.*]] = and i32 [[A:%.*]], 78
+; CHECK-NEXT:    [[TST2:%.*]] = icmp eq i32 [[MASK2]], [[A]]
+; CHECK-NEXT:    ret i1 [[TST2]]
+;
+  %mask1 = and i32 %A, 14
+  %tst1 = icmp eq i32 %mask1, %A
+  %mask2 = and i32 %A, 78
+  %tst2 = icmp eq i32 %mask2, %A
+  %res = select i1 %tst1, i1 true, i1 %tst2
+  ret i1 %res
+}
+
 define i1 @masked_or_A_slightly_optimized(i32 %A) {
 ; CHECK-LABEL: @masked_or_A_slightly_optimized(
 ; CHECK-NEXT:    [[T0:%.*]] = icmp ult i32 [[A:%.*]], 8
@@ -115,6 +214,21 @@ define i1 @masked_or_A_slightly_optimized(i32 %A) {
   ret i1 %res
 }
 
+define i1 @masked_or_A_slightly_optimized_logical(i32 %A) {
+; CHECK-LABEL: @masked_or_A_slightly_optimized_logical(
+; CHECK-NEXT:    [[T0:%.*]] = icmp ult i32 [[A:%.*]], 8
+; CHECK-NEXT:    [[MASK2:%.*]] = and i32 [[A]], 39
+; CHECK-NEXT:    [[TST2:%.*]] = icmp eq i32 [[MASK2]], [[A]]
+; CHECK-NEXT:    [[RES:%.*]] = or i1 [[T0]], [[TST2]]
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %t0 = icmp ult i32 %A, 8
+  %mask2 = and i32 %A, 39
+  %tst2 = icmp eq i32 %mask2, %A
+  %res = select i1 %t0, i1 true, i1 %tst2
+  ret i1 %res
+}
+
 define i1 @masked_or_allzeroes_notoptimised(i32 %A) {
 ; CHECK-LABEL: @masked_or_allzeroes_notoptimised(
 ; CHECK-NEXT:    [[MASK1:%.*]] = and i32 [[A:%.*]], 15
@@ -132,6 +246,23 @@ define i1 @masked_or_allzeroes_notoptimised(i32 %A) {
   ret i1 %res
 }
 
+define i1 @masked_or_allzeroes_notoptimised_logical(i32 %A) {
+; CHECK-LABEL: @masked_or_allzeroes_notoptimised_logical(
+; CHECK-NEXT:    [[MASK1:%.*]] = and i32 [[A:%.*]], 15
+; CHECK-NEXT:    [[TST1:%.*]] = icmp eq i32 [[MASK1]], 0
+; CHECK-NEXT:    [[MASK2:%.*]] = and i32 [[A]], 39
+; CHECK-NEXT:    [[TST2:%.*]] = icmp eq i32 [[MASK2]], 0
+; CHECK-NEXT:    [[RES:%.*]] = or i1 [[TST1]], [[TST2]]
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %mask1 = and i32 %A, 15
+  %tst1 = icmp eq i32 %mask1, 0
+  %mask2 = and i32 %A, 39
+  %tst2 = icmp eq i32 %mask2, 0
+  %res = select i1 %tst1, i1 true, i1 %tst2
+  ret i1 %res
+}
+
 define i1 @nomask_lhs(i32 %in) {
 ; CHECK-LABEL: @nomask_lhs(
 ; CHECK-NEXT:    [[MASKED:%.*]] = and i32 [[IN:%.*]], 1
@@ -145,6 +276,19 @@ define i1 @nomask_lhs(i32 %in) {
   ret i1 %val
 }
 
+define i1 @nomask_lhs_logical(i32 %in) {
+; CHECK-LABEL: @nomask_lhs_logical(
+; CHECK-NEXT:    [[MASKED:%.*]] = and i32 [[IN:%.*]], 1
+; CHECK-NEXT:    [[TST2:%.*]] = icmp eq i32 [[MASKED]], 0
+; CHECK-NEXT:    ret i1 [[TST2]]
+;
+  %tst1 = icmp eq i32 %in, 0
+  %masked = and i32 %in, 1
+  %tst2 = icmp eq i32 %masked, 0
+  %val = select i1 %tst1, i1 true, i1 %tst2
+  ret i1 %val
+}
+
 define i1 @nomask_rhs(i32 %in) {
 ; CHECK-LABEL: @nomask_rhs(
 ; CHECK-NEXT:    [[MASKED:%.*]] = and i32 [[IN:%.*]], 1
@@ -158,6 +302,19 @@ define i1 @nomask_rhs(i32 %in) {
   ret i1 %val
 }
 
+define i1 @nomask_rhs_logical(i32 %in) {
+; CHECK-LABEL: @nomask_rhs_logical(
+; CHECK-NEXT:    [[MASKED:%.*]] = and i32 [[IN:%.*]], 1
+; CHECK-NEXT:    [[TST1:%.*]] = icmp eq i32 [[MASKED]], 0
+; CHECK-NEXT:    ret i1 [[TST1]]
+;
+  %masked = and i32 %in, 1
+  %tst1 = icmp eq i32 %masked, 0
+  %tst2 = icmp eq i32 %in, 0
+  %val = select i1 %tst1, i1 true, i1 %tst2
+  ret i1 %val
+}
+
 ; TODO: This test simplifies to a constant, so the functionality and test could be in InstSimplify.
 
 define i1 @fold_mask_cmps_to_false(i32 %x) {
@@ -171,6 +328,17 @@ define i1 @fold_mask_cmps_to_false(i32 %x) {
   ret i1 %t4
 }
 
+define i1 @fold_mask_cmps_to_false_logical(i32 %x) {
+; CHECK-LABEL: @fold_mask_cmps_to_false_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %t1 = and i32 %x, 2147483647
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = icmp eq i32 %x, 2147483647
+  %t4 = select i1 %t3, i1 %t2, i1 false
+  ret i1 %t4
+}
+
 ; TODO: This test simplifies to a constant, so the functionality and test could be in InstSimplify.
 
 define i1 @fold_mask_cmps_to_true(i32 %x) {
@@ -184,6 +352,17 @@ define i1 @fold_mask_cmps_to_true(i32 %x) {
   ret i1 %t4
 }
 
+define i1 @fold_mask_cmps_to_true_logical(i32 %x) {
+; CHECK-LABEL: @fold_mask_cmps_to_true_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %t1 = and i32 %x, 2147483647
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = icmp ne i32 %x, 2147483647
+  %t4 = select i1 %t3, i1 true, i1 %t2
+  ret i1 %t4
+}
+
 ; PR32401 - https://bugs.llvm.org/show_bug.cgi?id=32401
 
 define i1 @cmpeq_bitwise(i8 %a, i8 %b, i8 %c, i8 %d) {
@@ -232,6 +411,23 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_0(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_0_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_0_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 12
+; CHECK-NEXT:    [[T2:%.*]] = icmp ne i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X]], 3
+; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32 [[T3]], 1
+; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %x, 12
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 3
+  %t4 = icmp eq i32 %t3, 1
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 12) != 0 & (X & 7) == 1) -> (X & 15) == 9
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_1(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_1(
@@ -247,6 +443,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_1(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_1_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_1_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 9
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %t1 = and i32 %x, 12
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 7
+  %t4 = icmp eq i32 %t3, 1
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 14) != 0 & (X & 3) == 1) -> no change
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_1b(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_1b(
@@ -265,6 +475,23 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_1b(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_1b_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_1b_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 14
+; CHECK-NEXT:    [[T2:%.*]] = icmp ne i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X]], 3
+; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32 [[T3]], 1
+; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %x, 14
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 3
+  %t4 = icmp eq i32 %t3, 1
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 3) != 0 & (X & 7) == 0) -> false
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_2(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_2(
@@ -278,6 +505,18 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_2(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_2_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_2_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %t1 = and i32 %x, 3
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 7
+  %t4 = icmp eq i32 %t3, 0
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 15) != 0 & (X & 7) == 0) -> (X & 15) == 8
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_3(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_3(
@@ -293,6 +532,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_3(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_3_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_3_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 8
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %t1 = and i32 %x, 15
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 7
+  %t4 = icmp eq i32 %t3, 0
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 15) != 0 & (X & 3) == 0) -> no change
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_3b(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_3b(
@@ -311,6 +564,23 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_3b(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_3b_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_3b_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T2:%.*]] = icmp ne i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X]], 3
+; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32 [[T3]], 0
+; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %x, 15
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 3
+  %t4 = icmp eq i32 %t3, 0
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 255) != 0 & (X & 15) == 8) -> (X & 15) == 8
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_4(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_4(
@@ -326,6 +596,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_4(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_4_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_4_logical(
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32 [[T3]], 8
+; CHECK-NEXT:    ret i1 [[T4]]
+;
+  %t1 = and i32 %x, 255
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp eq i32 %t3, 8
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 15) != 0 & (X & 15) == 8) -> (X & 15) == 8
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_5(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_5(
@@ -341,6 +625,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_5(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_5_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_5_logical(
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32 [[T3]], 8
+; CHECK-NEXT:    ret i1 [[T4]]
+;
+  %t1 = and i32 %x, 15
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp eq i32 %t3, 8
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 12) != 0 & (X & 15) == 8) -> (X & 15) == 8
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_6(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_6(
@@ -356,6 +654,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_6(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_6_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_6_logical(
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32 [[T3]], 8
+; CHECK-NEXT:    ret i1 [[T4]]
+;
+  %t1 = and i32 %x, 12
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp eq i32 %t3, 8
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 7) != 0 & (X & 15) == 8) -> false
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_7(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_7(
@@ -369,6 +681,18 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_7(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_7_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_7_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %t1 = and i32 %x, 7
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp eq i32 %t3, 8
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 6) != 0 & (X & 15) == 8) -> false
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_7b(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_7b(
@@ -382,7 +706,19 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_7b(i32 %x) {
   ret i1 %t5
 }
 
-; ((X & 12) == 0 | (X & 3) != 1) -> !((X & 12) != 0 & (X & 3) == 1)) ->
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_7b_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_7b_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %t1 = and i32 %x, 6
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp eq i32 %t3, 8
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
+; ((X & 12) == 0 | (X & 3) != 1) -> !((X & 12) != 0 & (X & 3) == 1)) ->
 ; no change
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_0(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_0(
@@ -401,6 +737,23 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_0(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_0_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_0_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 12
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X]], 3
+; CHECK-NEXT:    [[T4:%.*]] = icmp ne i32 [[T3]], 1
+; CHECK-NEXT:    [[T5:%.*]] = or i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %x, 12
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 3
+  %t4 = icmp ne i32 %t3, 1
+  %t5 = select i1 %t2, i1 true, i1 %t4
+  ret i1 %t5
+}
+
 ; ((X & 12) == 0 | (X & 7) != 1) -> !((X & 12) != 0 & (X & 7) == 1) ->
 ; !((X & 15) == 9) -> (X & 15) != 9
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_1(i32 %x) {
@@ -417,6 +770,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_1(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_1_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_1_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 9
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %t1 = and i32 %x, 12
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 7
+  %t4 = icmp ne i32 %t3, 1
+  %t5 = select i1 %t2, i1 true, i1 %t4
+  ret i1 %t5
+}
+
 ; ((X & 14) == 0 | (X & 3) != 1) -> !((X & 14) != 0 & (X & 3) == 1) ->
 ; no change.
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_1b(i32 %x) {
@@ -436,6 +803,23 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_1b(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_1b_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_1b_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 14
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X]], 3
+; CHECK-NEXT:    [[T4:%.*]] = icmp ne i32 [[T3]], 1
+; CHECK-NEXT:    [[T5:%.*]] = or i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %x, 14
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 3
+  %t4 = icmp ne i32 %t3, 1
+  %t5 = select i1 %t2, i1 true, i1 %t4
+  ret i1 %t5
+}
+
 ; ((X & 3) == 0 | (X & 7) != 0) -> !((X & 3) != 0 & (X & 7) == 0) ->
 ; !(false) -> true
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_2(i32 %x) {
@@ -450,6 +834,18 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_2(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_2_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_2_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %t1 = and i32 %x, 3
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 7
+  %t4 = icmp ne i32 %t3, 0
+  %t5 = select i1 %t2, i1 true, i1 %t4
+  ret i1 %t5
+}
+
 ; ((X & 15) == 0 | (X & 7) != 0) -> !((X & 15) != 0 & (X & 7) == 0) ->
 ; !((X & 15) == 8) -> (X & 15) != 8
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_3(i32 %x) {
@@ -466,6 +862,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_3(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_3_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_3_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 8
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %t1 = and i32 %x, 15
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 7
+  %t4 = icmp ne i32 %t3, 0
+  %t5 = select i1 %t2, i1 true, i1 %t4
+  ret i1 %t5
+}
+
 ; ((X & 15) == 0 | (X & 3) != 0) -> !((X & 15) != 0 & (X & 3) == 0) ->
 ; no change.
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_3b(i32 %x) {
@@ -485,6 +895,23 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_3b(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_3b_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_3b_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X]], 3
+; CHECK-NEXT:    [[T4:%.*]] = icmp ne i32 [[T3]], 0
+; CHECK-NEXT:    [[T5:%.*]] = or i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %x, 15
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 3
+  %t4 = icmp ne i32 %t3, 0
+  %t5 = select i1 %t2, i1 true, i1 %t4
+  ret i1 %t5
+}
+
 ; ((X & 255) == 0 | (X & 15) != 8) -> !(((X & 255) != 0 & (X & 15) == 8)) ->
 ; !((X & 15) == 8) -> ((X & 15) != 8)
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_4(i32 %x) {
@@ -501,6 +928,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_4(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_4_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_4_logical(
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T4:%.*]] = icmp ne i32 [[T3]], 8
+; CHECK-NEXT:    ret i1 [[T4]]
+;
+  %t1 = and i32 %x, 255
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp ne i32 %t3, 8
+  %t5 = select i1 %t2, i1 true, i1 %t4
+  ret i1 %t5
+}
+
 ; ((X & 15) == 0 | (X & 15) != 8) -> !(((X & 15) != 0 & (X & 15) == 8)) ->
 ; !((X & 15) == 8) -> ((X & 15) != 8)
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_5(i32 %x) {
@@ -517,6 +958,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_5(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_5_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_5_logical(
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T4:%.*]] = icmp ne i32 [[T3]], 8
+; CHECK-NEXT:    ret i1 [[T4]]
+;
+  %t1 = and i32 %x, 15
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp ne i32 %t3, 8
+  %t5 = select i1 %t2, i1 true, i1 %t4
+  ret i1 %t5
+}
+
 ; ((X & 12) == 0 | (X & 15) != 8) -> !(((X & 12) != 0 & (X & 15) == 8)) ->
 ; !((X & 15) == 8) -> ((X & 15) != 8
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_6(i32 %x) {
@@ -533,6 +988,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_6(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_6_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_6_logical(
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T4:%.*]] = icmp ne i32 [[T3]], 8
+; CHECK-NEXT:    ret i1 [[T4]]
+;
+  %t1 = and i32 %x, 12
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp ne i32 %t3, 8
+  %t5 = select i1 %t2, i1 true, i1 %t4
+  ret i1 %t5
+}
+
 ; ((X & 7) == 0 | (X & 15) != 8) -> !(((X & 7) != 0 & (X & 15) == 8)) ->
 ; !(false) -> true
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_7(i32 %x) {
@@ -547,6 +1016,18 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_7(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_7_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_7_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %t1 = and i32 %x, 7
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp ne i32 %t3, 8
+  %t5 = select i1 %t2, i1 true, i1 %t4
+  ret i1 %t5
+}
+
 ; ((X & 6) == 0 | (X & 15) != 8) -> !(((X & 6) != 0 & (X & 15) == 8)) ->
 ; !(false) -> true
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_7b(i32 %x) {
@@ -561,6 +1042,18 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_7b(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_7b_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_7b_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %t1 = and i32 %x, 6
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp ne i32 %t3, 8
+  %t5 = select i1 %t2, i1 true, i1 %t4
+  ret i1 %t5
+}
+
 
 ; ((X & 12) != 0 & (X & 3) == 1) -> no change
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_0(i32 %x) {
@@ -580,6 +1073,23 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_0(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_0_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_0_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 12
+; CHECK-NEXT:    [[T2:%.*]] = icmp ne i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X]], 3
+; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32 [[T3]], 1
+; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T4]], [[T2]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %x, 12
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 3
+  %t4 = icmp eq i32 %t3, 1
+  %t5 = select i1 %t4, i1 %t2, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 12) != 0 & (X & 7) == 1) -> (X & 15) == 9
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_1(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_1(
@@ -595,6 +1105,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_1(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_1_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_1_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 9
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %t1 = and i32 %x, 12
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 7
+  %t4 = icmp eq i32 %t3, 1
+  %t5 = select i1 %t4, i1 %t2, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 14) != 0 & (X & 3) == 1) -> no change
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_1b(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_1b(
@@ -613,6 +1137,23 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_1b(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_1b_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_1b_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 14
+; CHECK-NEXT:    [[T2:%.*]] = icmp ne i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X]], 3
+; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32 [[T3]], 1
+; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T4]], [[T2]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %x, 14
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 3
+  %t4 = icmp eq i32 %t3, 1
+  %t5 = select i1 %t4, i1 %t2, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 3) != 0 & (X & 7) == 0) -> false
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_2(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_2(
@@ -626,6 +1167,18 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_2(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_2_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_2_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %t1 = and i32 %x, 3
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 7
+  %t4 = icmp eq i32 %t3, 0
+  %t5 = select i1 %t4, i1 %t2, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 15) != 0 & (X & 7) == 0) -> (X & 15) == 8
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_3(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_3(
@@ -641,6 +1194,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_3(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_3_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_3_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 8
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %t1 = and i32 %x, 15
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 7
+  %t4 = icmp eq i32 %t3, 0
+  %t5 = select i1 %t4, i1 %t2, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 15) != 0 & (X & 3) == 0) -> no change
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_3b(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_3b(
@@ -659,6 +1226,23 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_3b(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_3b_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_3b_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T2:%.*]] = icmp ne i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X]], 3
+; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32 [[T3]], 0
+; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T4]], [[T2]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %x, 15
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 3
+  %t4 = icmp eq i32 %t3, 0
+  %t5 = select i1 %t4, i1 %t2, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 255) != 0 & (X & 15) == 8) -> (X & 15) == 8
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_4(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_4(
@@ -674,6 +1258,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_4(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_4_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_4_logical(
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32 [[T3]], 8
+; CHECK-NEXT:    ret i1 [[T4]]
+;
+  %t1 = and i32 %x, 255
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp eq i32 %t3, 8
+  %t5 = select i1 %t4, i1 %t2, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 15) != 0 & (X & 15) == 8) -> (X & 15) == 8
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_5(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_5(
@@ -689,6 +1287,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_5(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_5_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_5_logical(
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32 [[T3]], 8
+; CHECK-NEXT:    ret i1 [[T4]]
+;
+  %t1 = and i32 %x, 15
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp eq i32 %t3, 8
+  %t5 = select i1 %t4, i1 %t2, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 12) != 0 & (X & 15) == 8) -> (X & 15) == 8
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_6(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_6(
@@ -704,6 +1316,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_6(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_6_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_6_logical(
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T4:%.*]] = icmp eq i32 [[T3]], 8
+; CHECK-NEXT:    ret i1 [[T4]]
+;
+  %t1 = and i32 %x, 12
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp eq i32 %t3, 8
+  %t5 = select i1 %t4, i1 %t2, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 7) != 0 & (X & 15) == 8) -> false
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_7(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_7(
@@ -717,6 +1343,18 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_7(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_7_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_7_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %t1 = and i32 %x, 7
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp eq i32 %t3, 8
+  %t5 = select i1 %t4, i1 %t2, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 6) != 0 & (X & 15) == 8) -> false
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_7b(i32 %x) {
 ; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_7b(
@@ -730,6 +1368,18 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_7b(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_swapped_7b_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_swapped_7b_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %t1 = and i32 %x, 6
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp eq i32 %t3, 8
+  %t5 = select i1 %t4, i1 %t2, i1 false
+  ret i1 %t5
+}
+
 ; ((X & 12) == 0 | (X & 3) != 1) -> !((X & 12) != 0 & (X & 3) == 1)) ->
 ; no change
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_0(i32 %x) {
@@ -749,6 +1399,23 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_0(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_0_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_0_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 12
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X]], 3
+; CHECK-NEXT:    [[T4:%.*]] = icmp ne i32 [[T3]], 1
+; CHECK-NEXT:    [[T5:%.*]] = or i1 [[T4]], [[T2]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %x, 12
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 3
+  %t4 = icmp ne i32 %t3, 1
+  %t5 = select i1 %t4, i1 true, i1 %t2
+  ret i1 %t5
+}
+
 ; ((X & 12) == 0 | (X & 7) != 1) -> !((X & 12) != 0 & (X & 7) == 1) ->
 ; !((X & 15) == 9) -> (X & 15) != 9
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1(i32 %x) {
@@ -765,6 +1432,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 9
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %t1 = and i32 %x, 12
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 7
+  %t4 = icmp ne i32 %t3, 1
+  %t5 = select i1 %t4, i1 true, i1 %t2
+  ret i1 %t5
+}
+
 ; ((X & 14) == 0 | (X & 3) != 1) -> !((X & 14) != 0 & (X & 3) == 1) ->
 ; no change.
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1b(i32 %x) {
@@ -784,6 +1465,23 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1b(i32 %x)
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1b_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1b_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 14
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X]], 3
+; CHECK-NEXT:    [[T4:%.*]] = icmp ne i32 [[T3]], 1
+; CHECK-NEXT:    [[T5:%.*]] = or i1 [[T4]], [[T2]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %x, 14
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 3
+  %t4 = icmp ne i32 %t3, 1
+  %t5 = select i1 %t4, i1 true, i1 %t2
+  ret i1 %t5
+}
+
 ; ((X & 3) == 0 | (X & 7) != 0) -> !((X & 3) != 0 & (X & 7) == 0) ->
 ; !(false) -> true
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2(i32 %x) {
@@ -798,6 +1496,18 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %t1 = and i32 %x, 3
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 7
+  %t4 = icmp ne i32 %t3, 0
+  %t5 = select i1 %t4, i1 true, i1 %t2
+  ret i1 %t5
+}
+
 ; ((X & 15) == 0 | (X & 7) != 0) -> !((X & 15) != 0 & (X & 7) == 0) ->
 ; !((X & 15) == 8) -> (X & 15) != 8
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3(i32 %x) {
@@ -814,6 +1524,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 8
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %t1 = and i32 %x, 15
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 7
+  %t4 = icmp ne i32 %t3, 0
+  %t5 = select i1 %t4, i1 true, i1 %t2
+  ret i1 %t5
+}
+
 ; ((X & 15) == 0 | (X & 3) != 0) -> !((X & 15) != 0 & (X & 3) == 0) ->
 ; no change.
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3b(i32 %x) {
@@ -833,6 +1557,23 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3b(i32 %x)
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3b_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3b_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X]], 3
+; CHECK-NEXT:    [[T4:%.*]] = icmp ne i32 [[T3]], 0
+; CHECK-NEXT:    [[T5:%.*]] = or i1 [[T4]], [[T2]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %x, 15
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 3
+  %t4 = icmp ne i32 %t3, 0
+  %t5 = select i1 %t4, i1 true, i1 %t2
+  ret i1 %t5
+}
+
 ; ((X & 255) == 0 | (X & 15) != 8) -> !(((X & 255) != 0 & (X & 15) == 8)) ->
 ; !((X & 15) == 8) -> ((X & 15) != 8)
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_4(i32 %x) {
@@ -849,6 +1590,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_4(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_4_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_4_logical(
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T4:%.*]] = icmp ne i32 [[T3]], 8
+; CHECK-NEXT:    ret i1 [[T4]]
+;
+  %t1 = and i32 %x, 255
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp ne i32 %t3, 8
+  %t5 = select i1 %t4, i1 true, i1 %t2
+  ret i1 %t5
+}
+
 ; ((X & 15) == 0 | (X & 15) != 8) -> !(((X & 15) != 0 & (X & 15) == 8)) ->
 ; !((X & 15) == 8) -> ((X & 15) != 8)
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_5(i32 %x) {
@@ -865,6 +1620,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_5(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_5_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_5_logical(
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T4:%.*]] = icmp ne i32 [[T3]], 8
+; CHECK-NEXT:    ret i1 [[T4]]
+;
+  %t1 = and i32 %x, 15
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp ne i32 %t3, 8
+  %t5 = select i1 %t4, i1 true, i1 %t2
+  ret i1 %t5
+}
+
 ; ((X & 12) == 0 | (X & 15) != 8) -> !(((X & 12) != 0 & (X & 15) == 8)) ->
 ; !((X & 15) == 8) -> ((X & 15) != 8
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6(i32 %x) {
@@ -881,6 +1650,20 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_logical(
+; CHECK-NEXT:    [[T3:%.*]] = and i32 [[X:%.*]], 15
+; CHECK-NEXT:    [[T4:%.*]] = icmp ne i32 [[T3]], 8
+; CHECK-NEXT:    ret i1 [[T4]]
+;
+  %t1 = and i32 %x, 12
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp ne i32 %t3, 8
+  %t5 = select i1 %t4, i1 true, i1 %t2
+  ret i1 %t5
+}
+
 ; ((X & 7) == 0 | (X & 15) != 8) -> !(((X & 7) != 0 & (X & 15) == 8)) ->
 ; !(false) -> true
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7(i32 %x) {
@@ -895,6 +1678,18 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7(i32 %x) {
   ret i1 %t5
 }
 
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %t1 = and i32 %x, 7
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp ne i32 %t3, 8
+  %t5 = select i1 %t4, i1 true, i1 %t2
+  ret i1 %t5
+}
+
 ; ((X & 6) == 0 | (X & 15) != 8) -> !(((X & 6) != 0 & (X & 15) == 8)) ->
 ; !(false) -> true
 define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7b(i32 %x) {
@@ -908,3 +1703,15 @@ define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7b(i32 %x)
   %t5 = or i1 %t4, %t2
   ret i1 %t5
 }
+
+define i1 @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7b_logical(i32 %x) {
+; CHECK-LABEL: @masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7b_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %t1 = and i32 %x, 6
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = and i32 %x, 15
+  %t4 = icmp ne i32 %t3, 8
+  %t5 = select i1 %t4, i1 true, i1 %t2
+  ret i1 %t5
+}

diff  --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index b21077e2e2ef..b48466e678d8 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -970,6 +970,22 @@ define i1 @test52(i32 %x1) {
   ret i1 %A
 }
 
+define i1 @test52_logical(i32 %x1) {
+; CHECK-LABEL: @test52_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X1:%.*]], 16711935
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 4980863
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %conv = and i32 %x1, 255
+  %cmp = icmp eq i32 %conv, 127
+  %i2 = lshr i32 %x1, 16
+  %i3 = trunc i32 %i2 to i8
+  %cmp15 = icmp eq i8 %i3, 76
+
+  %A = select i1 %cmp, i1 %cmp15, i1 false
+  ret i1 %A
+}
+
 define i1 @test52b(i128 %x1) {
 ; CHECK-LABEL: @test52b(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935
@@ -986,6 +1002,22 @@ define i1 @test52b(i128 %x1) {
   ret i1 %A
 }
 
+define i1 @test52b_logical(i128 %x1) {
+; CHECK-LABEL: @test52b_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i128 [[X1:%.*]], 16711935
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i128 [[TMP1]], 4980863
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %conv = and i128 %x1, 255
+  %cmp = icmp eq i128 %conv, 127
+  %i2 = lshr i128 %x1, 16
+  %i3 = trunc i128 %i2 to i8
+  %cmp15 = icmp eq i8 %i3, 76
+
+  %A = select i1 %cmp, i1 %cmp15, i1 false
+  ret i1 %A
+}
+
 ; PR9838
 define i1 @test53(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test53(
@@ -1841,6 +1873,24 @@ define i1 @icmp_and_shr_multiuse(i32 %X) {
   ret i1 %and3
 }
 
+define i1 @icmp_and_shr_multiuse_logical(i32 %X) {
+; CHECK-LABEL: @icmp_and_shr_multiuse_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
+; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
+; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
+; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
+; CHECK-NEXT:    ret i1 [[AND3]]
+;
+  %shr = lshr i32 %X, 4
+  %and = and i32 %shr, 15
+  %and2 = and i32 %shr, 31 ; second use of the shift
+  %tobool = icmp ne i32 %and, 14
+  %tobool2 = icmp ne i32 %and2, 27
+  %and3 = select i1 %tobool, i1 %tobool2, i1 false
+  ret i1 %and3
+}
+
 ; Variation of the above with an ashr
 define i1 @icmp_and_ashr_multiuse(i32 %X) {
 ; CHECK-LABEL: @icmp_and_ashr_multiuse(
@@ -1860,6 +1910,24 @@ define i1 @icmp_and_ashr_multiuse(i32 %X) {
   ret i1 %and3
 }
 
+define i1 @icmp_and_ashr_multiuse_logical(i32 %X) {
+; CHECK-LABEL: @icmp_and_ashr_multiuse_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 240
+; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 224
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[X]], 496
+; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp ne i32 [[TMP2]], 432
+; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[TOBOOL]], [[TOBOOL2]]
+; CHECK-NEXT:    ret i1 [[AND3]]
+;
+  %shr = ashr i32 %X, 4
+  %and = and i32 %shr, 15
+  %and2 = and i32 %shr, 31 ; second use of the shift
+  %tobool = icmp ne i32 %and, 14
+  %tobool2 = icmp ne i32 %and2, 27
+  %and3 = select i1 %tobool, i1 %tobool2, i1 false
+  ret i1 %and3
+}
+
 define i1 @icmp_lshr_and_overshift(i8 %X) {
 ; CHECK-LABEL: @icmp_lshr_and_overshift(
 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ugt i8 [[X:%.*]], 31
@@ -2162,6 +2230,18 @@ define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) {
   ret i1 %3
 }
 
+define i1 @or_icmp_eq_B_0_icmp_ult_A_B_logical(i64 %a, i64 %b) {
+; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[B:%.*]], -1
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i64 [[TMP1]], [[A:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %1 = icmp eq i64 %b, 0
+  %2 = icmp ult i64 %a, %b
+  %3 = select i1 %1, i1 true, i1 %2
+  ret i1 %3
+}
+
 define <2 x i1> @or_icmp_eq_B_0_icmp_ult_A_B_uniform(<2 x i64> %a, <2 x i64> %b) {
 ; CHECK-LABEL: @or_icmp_eq_B_0_icmp_ult_A_B_uniform(
 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i64> [[B:%.*]], <i64 -1, i64 -1>
@@ -2198,6 +2278,18 @@ define i1 @or_icmp_ne_A_0_icmp_ne_B_0(i64 %a, i64 %b) {
   ret i1 %3
 }
 
+define i1 @or_icmp_ne_A_0_icmp_ne_B_0_logical(i64 %a, i64 %b) {
+; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[TMP1]], 0
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %1 = icmp ne i64 %a, 0
+  %2 = icmp ne i64 %b, 0
+  %3 = select i1 %1, i1 true, i1 %2
+  ret i1 %3
+}
+
 define <2 x i1> @or_icmp_ne_A_0_icmp_ne_B_0_uniform(<2 x i64> %a, <2 x i64> %b) {
 ; CHECK-LABEL: @or_icmp_ne_A_0_icmp_ne_B_0_uniform(
 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i64> [[A:%.*]], [[B:%.*]]

diff  --git a/llvm/test/Transforms/InstCombine/ispow2.ll b/llvm/test/Transforms/InstCombine/ispow2.ll
index f0d4a80ccfb0..c54c6271ec07 100644
--- a/llvm/test/Transforms/InstCombine/ispow2.ll
+++ b/llvm/test/Transforms/InstCombine/ispow2.ll
@@ -3,7 +3,7 @@
 
 define i1 @is_pow2or0_negate_op(i32 %x) {
 ; CHECK-LABEL: @is_pow2or0_negate_op(
-; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0:!range !.*]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP1]], 2
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
@@ -27,7 +27,7 @@ define <2 x i1> @is_pow2or0_negate_op_vec(<2 x i32> %x) {
 
 define i1 @is_pow2or0_decrement_op(i8 %x) {
 ; CHECK-LABEL: @is_pow2or0_decrement_op(
-; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.ctpop.i8(i8 [[X:%.*]]), !range !1
+; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.ctpop.i8(i8 [[X:%.*]]), [[RNG1:!range !.*]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[TMP1]], 2
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
@@ -51,7 +51,7 @@ define <2 x i1> @is_pow2or0_decrement_op_vec(<2 x i8> %x) {
 
 define i1 @isnot_pow2or0_negate_op(i32 %x) {
 ; CHECK-LABEL: @isnot_pow2or0_negate_op(
-; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[TMP1]], 1
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
@@ -75,7 +75,7 @@ define <2 x i1> @isnot_pow2or0_negate_op_vec(<2 x i32> %x) {
 
 define i1 @isnot_pow2or0_decrement_op(i8 %x) {
 ; CHECK-LABEL: @isnot_pow2or0_decrement_op(
-; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.ctpop.i8(i8 [[X:%.*]]), !range !1
+; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.ctpop.i8(i8 [[X:%.*]]), [[RNG1]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[TMP1]], 1
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
@@ -100,7 +100,7 @@ define <2 x i1> @isnot_pow2or0_decrement_op_vec(<2 x i8> %x) {
 define i1 @is_pow2or0_negate_op_commute1(i32 %p) {
 ; CHECK-LABEL: @is_pow2or0_negate_op_commute1(
 ; CHECK-NEXT:    [[X:%.*]] = srem i32 42, [[P:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X]]), !range !2
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X]]), [[RNG2:!range !.*]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP1]], 2
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
@@ -116,7 +116,7 @@ define i1 @is_pow2or0_negate_op_commute1(i32 %p) {
 define i1 @isnot_pow2or0_negate_op_commute2(i32 %p) {
 ; CHECK-LABEL: @isnot_pow2or0_negate_op_commute2(
 ; CHECK-NEXT:    [[X:%.*]] = urem i32 42, [[P:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X]]), !range !3
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X]]), [[RNG3:!range !.*]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[TMP1]], 1
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
@@ -130,7 +130,7 @@ define i1 @isnot_pow2or0_negate_op_commute2(i32 %p) {
 define i1 @isnot_pow2or0_negate_op_commute3(i32 %p) {
 ; CHECK-LABEL: @isnot_pow2or0_negate_op_commute3(
 ; CHECK-NEXT:    [[X:%.*]] = urem i32 42, [[P:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X]]), !range !3
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X]]), [[RNG3]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[TMP1]], 1
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
@@ -147,7 +147,7 @@ define i1 @is_pow2or0_negate_op_extra_use1(i32 %x) {
 ; CHECK-LABEL: @is_pow2or0_negate_op_extra_use1(
 ; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[X:%.*]]
 ; CHECK-NEXT:    call void @use(i32 [[NEG]])
-; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X]]), !range !0
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X]]), [[RNG0]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[TMP1]], 2
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
@@ -180,7 +180,7 @@ declare <2 x i8> @llvm.ctpop.v2i8(<2 x i8>)
 
 define i1 @is_pow2_ctpop(i32 %x) {
 ; CHECK-LABEL: @is_pow2_ctpop(
-; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[T0]], 1
 ; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
@@ -191,12 +191,25 @@ define i1 @is_pow2_ctpop(i32 %x) {
   ret i1 %r
 }
 
+define i1 @is_pow2_ctpop_logical(i32 %x) {
+; CHECK-LABEL: @is_pow2_ctpop_logical(
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[T0]], 1
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
+  %cmp = icmp ult i32 %t0, 2
+  %notzero = icmp ne i32 %x, 0
+  %r = select i1 %notzero, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 ; Extra uses don't change the fold.
 declare void @use_i1(i1)
 
 define i1 @is_pow2_ctpop_extra_uses(i32 %x) {
 ; CHECK-LABEL: @is_pow2_ctpop_extra_uses(
-; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[T0]], 2
 ; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])
 ; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0
@@ -213,6 +226,25 @@ define i1 @is_pow2_ctpop_extra_uses(i32 %x) {
   ret i1 %r
 }
 
+define i1 @is_pow2_ctpop_extra_uses_logical(i32 %x) {
+; CHECK-LABEL: @is_pow2_ctpop_extra_uses_logical(
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[T0]], 2
+; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])
+; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0
+; CHECK-NEXT:    call void @use_i1(i1 [[NOTZERO]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[T0]], 1
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
+  %cmp = icmp ult i32 %t0, 2
+  call void @use_i1(i1 %cmp)
+  %notzero = icmp ne i32 %x, 0
+  call void @use_i1(i1 %notzero)
+  %r = select i1 %notzero, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 ; Test vector type and commuted 'and' operands.
 
 define <2 x i1> @is_pow2_ctpop_commute_vec(<2 x i8> %x) {
@@ -232,7 +264,7 @@ define <2 x i1> @is_pow2_ctpop_commute_vec(<2 x i8> %x) {
 
 define i1 @is_pow2_ctpop_wrong_cmp_op1(i32 %x) {
 ; CHECK-LABEL: @is_pow2_ctpop_wrong_cmp_op1(
-; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[T0]], 3
 ; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0
 ; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOTZERO]], [[CMP]]
@@ -245,11 +277,26 @@ define i1 @is_pow2_ctpop_wrong_cmp_op1(i32 %x) {
   ret i1 %r
 }
 
+define i1 @is_pow2_ctpop_wrong_cmp_op1_logical(i32 %x) {
+; CHECK-LABEL: @is_pow2_ctpop_wrong_cmp_op1_logical(
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[T0]], 3
+; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOTZERO]], [[CMP]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
+  %cmp = icmp ult i32 %t0, 3
+  %notzero = icmp ne i32 %x, 0
+  %r = select i1 %notzero, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 ; Negative test - wrong constant.
 
 define i1 @is_pow2_ctpop_wrong_cmp_op2(i32 %x) {
 ; CHECK-LABEL: @is_pow2_ctpop_wrong_cmp_op2(
-; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[T0]], 2
 ; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 1
 ; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOTZERO]], [[CMP]]
@@ -262,11 +309,26 @@ define i1 @is_pow2_ctpop_wrong_cmp_op2(i32 %x) {
   ret i1 %r
 }
 
+define i1 @is_pow2_ctpop_wrong_cmp_op2_logical(i32 %x) {
+; CHECK-LABEL: @is_pow2_ctpop_wrong_cmp_op2_logical(
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[T0]], 2
+; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 1
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOTZERO]], [[CMP]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
+  %cmp = icmp ult i32 %t0, 2
+  %notzero = icmp ne i32 %x, 1
+  %r = select i1 %notzero, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 ; Negative test - wrong predicate.
 
 define i1 @is_pow2_ctpop_wrong_pred1(i32 %x) {
 ; CHECK-LABEL: @is_pow2_ctpop_wrong_pred1(
-; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[T0]], 2
 ; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0
 ; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOTZERO]], [[CMP]]
@@ -279,11 +341,26 @@ define i1 @is_pow2_ctpop_wrong_pred1(i32 %x) {
   ret i1 %r
 }
 
+define i1 @is_pow2_ctpop_wrong_pred1_logical(i32 %x) {
+; CHECK-LABEL: @is_pow2_ctpop_wrong_pred1_logical(
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[T0]], 2
+; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOTZERO]], [[CMP]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
+  %cmp = icmp ugt i32 %t0, 2
+  %notzero = icmp ne i32 %x, 0
+  %r = select i1 %notzero, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 ; Negative test - wrong predicate.
 
 define i1 @is_pow2_ctpop_wrong_pred2(i32 %x) {
 ; CHECK-LABEL: @is_pow2_ctpop_wrong_pred2(
-; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[T0]], 2
 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[X]], 0
 ; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP2]], [[CMP]]
@@ -296,11 +373,26 @@ define i1 @is_pow2_ctpop_wrong_pred2(i32 %x) {
   ret i1 %r
 }
 
+define i1 @is_pow2_ctpop_wrong_pred2_logical(i32 %x) {
+; CHECK-LABEL: @is_pow2_ctpop_wrong_pred2_logical(
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[T0]], 2
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[X]], 0
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP2]], [[CMP]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
+  %cmp = icmp ult i32 %t0, 2
+  %cmp2 = icmp sgt i32 %x, 0
+  %r = select i1 %cmp2, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 ; (X == 0) || (ctpop(X) u> 1) --> ctpop(X) != 1
 
 define i1 @isnot_pow2_ctpop(i32 %x) {
 ; CHECK-LABEL: @isnot_pow2_ctpop(
-; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[T0]], 1
 ; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
@@ -311,11 +403,24 @@ define i1 @isnot_pow2_ctpop(i32 %x) {
   ret i1 %r
 }
 
+define i1 @isnot_pow2_ctpop_logical(i32 %x) {
+; CHECK-LABEL: @isnot_pow2_ctpop_logical(
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[T0]], 1
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
+  %cmp = icmp ugt i32 %t0, 1
+  %iszero = icmp eq i32 %x, 0
+  %r = select i1 %iszero, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 ; Extra uses don't change the fold.
 
 define i1 @isnot_pow2_ctpop_extra_uses(i32 %x) {
 ; CHECK-LABEL: @isnot_pow2_ctpop_extra_uses(
-; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[T0]], 1
 ; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])
 ; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0
@@ -332,6 +437,25 @@ define i1 @isnot_pow2_ctpop_extra_uses(i32 %x) {
   ret i1 %r
 }
 
+define i1 @isnot_pow2_ctpop_extra_uses_logical(i32 %x) {
+; CHECK-LABEL: @isnot_pow2_ctpop_extra_uses_logical(
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[T0]], 1
+; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])
+; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0
+; CHECK-NEXT:    call void @use_i1(i1 [[ISZERO]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[T0]], 1
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
+  %cmp = icmp ugt i32 %t0, 1
+  call void @use_i1(i1 %cmp)
+  %iszero = icmp eq i32 %x, 0
+  call void @use_i1(i1 %iszero)
+  %r = select i1 %iszero, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 ; Test vector type and commuted 'or' operands.
 
 define <2 x i1> @isnot_pow2_ctpop_commute_vec(<2 x i8> %x) {
@@ -351,7 +475,7 @@ define <2 x i1> @isnot_pow2_ctpop_commute_vec(<2 x i8> %x) {
 
 define i1 @isnot_pow2_ctpop_wrong_cmp_op1(i32 %x) {
 ; CHECK-LABEL: @isnot_pow2_ctpop_wrong_cmp_op1(
-; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[T0]], 2
 ; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0
 ; CHECK-NEXT:    [[R:%.*]] = or i1 [[ISZERO]], [[CMP]]
@@ -364,11 +488,26 @@ define i1 @isnot_pow2_ctpop_wrong_cmp_op1(i32 %x) {
   ret i1 %r
 }
 
+define i1 @isnot_pow2_ctpop_wrong_cmp_op1_logical(i32 %x) {
+; CHECK-LABEL: @isnot_pow2_ctpop_wrong_cmp_op1_logical(
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[T0]], 2
+; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[ISZERO]], [[CMP]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
+  %cmp = icmp ugt i32 %t0, 2
+  %iszero = icmp eq i32 %x, 0
+  %r = select i1 %iszero, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 ; Negative test - wrong constant.
 
 define i1 @isnot_pow2_ctpop_wrong_cmp_op2(i32 %x) {
 ; CHECK-LABEL: @isnot_pow2_ctpop_wrong_cmp_op2(
-; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[T0]], 1
 ; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 1
 ; CHECK-NEXT:    [[R:%.*]] = or i1 [[ISZERO]], [[CMP]]
@@ -381,11 +520,26 @@ define i1 @isnot_pow2_ctpop_wrong_cmp_op2(i32 %x) {
   ret i1 %r
 }
 
+define i1 @isnot_pow2_ctpop_wrong_cmp_op2_logical(i32 %x) {
+; CHECK-LABEL: @isnot_pow2_ctpop_wrong_cmp_op2_logical(
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[T0]], 1
+; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 1
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[ISZERO]], [[CMP]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
+  %cmp = icmp ugt i32 %t0, 1
+  %iszero = icmp eq i32 %x, 1
+  %r = select i1 %iszero, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 ; Negative test - wrong predicate (but this could reduce).
 
 define i1 @isnot_pow2_ctpop_wrong_pred1(i32 %x) {
 ; CHECK-LABEL: @isnot_pow2_ctpop_wrong_pred1(
-; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[T0]], 1
 ; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0
 ; CHECK-NEXT:    [[R:%.*]] = or i1 [[ISZERO]], [[CMP]]
@@ -398,11 +552,26 @@ define i1 @isnot_pow2_ctpop_wrong_pred1(i32 %x) {
   ret i1 %r
 }
 
+define i1 @isnot_pow2_ctpop_wrong_pred1_logical(i32 %x) {
+; CHECK-LABEL: @isnot_pow2_ctpop_wrong_pred1_logical(
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[T0]], 1
+; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[ISZERO]], [[CMP]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
+  %cmp = icmp eq i32 %t0, 1
+  %iszero = icmp eq i32 %x, 0
+  %r = select i1 %iszero, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 ; Negative test - wrong predicate.
 
 define i1 @isnot_pow2_ctpop_wrong_pred2(i32 %x) {
 ; CHECK-LABEL: @isnot_pow2_ctpop_wrong_pred2(
-; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[T0]], 1
 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X]], 0
 ; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP2]], [[CMP]]
@@ -415,9 +584,24 @@ define i1 @isnot_pow2_ctpop_wrong_pred2(i32 %x) {
   ret i1 %r
 }
 
+define i1 @isnot_pow2_ctpop_wrong_pred2_logical(i32 %x) {
+; CHECK-LABEL: @isnot_pow2_ctpop_wrong_pred2_logical(
+; CHECK-NEXT:    [[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[T0]], 1
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X]], 0
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP2]], [[CMP]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
+  %cmp = icmp ugt i32 %t0, 1
+  %cmp2 = icmp slt i32 %x, 0
+  %r = select i1 %cmp2, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define i1 @is_pow2_negate_op(i32 %x) {
 ; CHECK-LABEL: @is_pow2_negate_op(
-; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
@@ -429,6 +613,20 @@ define i1 @is_pow2_negate_op(i32 %x) {
   ret i1 %r
 }
 
+define i1 @is_pow2_negate_op_logical(i32 %x) {
+; CHECK-LABEL: @is_pow2_negate_op_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %neg = sub i32 0, %x
+  %and = and i32 %neg, %x
+  %cmp = icmp eq i32 %and, %x
+  %notzero = icmp ne i32 %x, 0
+  %r = select i1 %notzero, i1 %cmp, i1 false
+  ret i1 %r
+}
+
 define <2 x i1> @is_pow2_negate_op_vec(<2 x i32> %x) {
 ; CHECK-LABEL: @is_pow2_negate_op_vec(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X:%.*]])
@@ -445,7 +643,7 @@ define <2 x i1> @is_pow2_negate_op_vec(<2 x i32> %x) {
 
 define i1 @is_pow2_decrement_op(i8 %x) {
 ; CHECK-LABEL: @is_pow2_decrement_op(
-; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.ctpop.i8(i8 [[X:%.*]]), !range !1
+; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.ctpop.i8(i8 [[X:%.*]]), [[RNG1]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 1
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
@@ -457,6 +655,20 @@ define i1 @is_pow2_decrement_op(i8 %x) {
   ret i1 %r
 }
 
+define i1 @is_pow2_decrement_op_logical(i8 %x) {
+; CHECK-LABEL: @is_pow2_decrement_op_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.ctpop.i8(i8 [[X:%.*]]), [[RNG1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 1
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %dec = add i8 %x, -1
+  %and = and i8 %dec, %x
+  %cmp = icmp eq i8 %and, 0
+  %notzero = icmp ne i8 %x, 0
+  %r = select i1 %cmp, i1 %notzero, i1 false
+  ret i1 %r
+}
+
 define <2 x i1> @is_pow2_decrement_op_vec(<2 x i8> %x) {
 ; CHECK-LABEL: @is_pow2_decrement_op_vec(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])
@@ -473,7 +685,7 @@ define <2 x i1> @is_pow2_decrement_op_vec(<2 x i8> %x) {
 
 define i1 @isnot_pow2_negate_op(i32 %x) {
 ; CHECK-LABEL: @isnot_pow2_negate_op(
-; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 1
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
@@ -485,6 +697,20 @@ define i1 @isnot_pow2_negate_op(i32 %x) {
   ret i1 %r
 }
 
+define i1 @isnot_pow2_negate_op_logical(i32 %x) {
+; CHECK-LABEL: @isnot_pow2_negate_op_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), [[RNG0]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 1
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %neg = sub i32 0, %x
+  %and = and i32 %neg, %x
+  %cmp = icmp ne i32 %and, %x
+  %iszero = icmp eq i32 %x, 0
+  %r = select i1 %cmp, i1 true, i1 %iszero
+  ret i1 %r
+}
+
 define <2 x i1> @isnot_pow2_negate_op_vec(<2 x i32> %x) {
 ; CHECK-LABEL: @isnot_pow2_negate_op_vec(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X:%.*]])
@@ -501,7 +727,7 @@ define <2 x i1> @isnot_pow2_negate_op_vec(<2 x i32> %x) {
 
 define i1 @isnot_pow2_decrement_op(i8 %x) {
 ; CHECK-LABEL: @isnot_pow2_decrement_op(
-; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.ctpop.i8(i8 [[X:%.*]]), !range !1
+; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.ctpop.i8(i8 [[X:%.*]]), [[RNG1]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 1
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
@@ -513,6 +739,20 @@ define i1 @isnot_pow2_decrement_op(i8 %x) {
   ret i1 %r
 }
 
+define i1 @isnot_pow2_decrement_op_logical(i8 %x) {
+; CHECK-LABEL: @isnot_pow2_decrement_op_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.ctpop.i8(i8 [[X:%.*]]), [[RNG1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 1
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %dec = add i8 %x, -1
+  %and = and i8 %dec, %x
+  %cmp = icmp ne i8 %and, 0
+  %iszero = icmp eq i8 %x, 0
+  %r = select i1 %iszero, i1 true, i1 %cmp
+  ret i1 %r
+}
+
 define <2 x i1> @isnot_pow2_decrement_op_vec(<2 x i8> %x) {
 ; CHECK-LABEL: @isnot_pow2_decrement_op_vec(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])

diff  --git a/llvm/test/Transforms/InstCombine/logical-select-inseltpoison.ll b/llvm/test/Transforms/InstCombine/logical-select-inseltpoison.ll
index 2f448ce1c740..f67cb024c2e3 100644
--- a/llvm/test/Transforms/InstCombine/logical-select-inseltpoison.ll
+++ b/llvm/test/Transforms/InstCombine/logical-select-inseltpoison.ll
@@ -376,6 +376,18 @@ define i1 @bools(i1 %a, i1 %b, i1 %c) {
   ret i1 %or
 }
 
+define i1 @bools_logical(i1 %a, i1 %b, i1 %c) {
+; CHECK-LABEL: @bools_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %not = xor i1 %c, -1
+  %and1 = select i1 %not, i1 %a, i1 false
+  %and2 = select i1 %c, i1 %b, i1 false
+  %or = select i1 %and1, i1 true, i1 %and2
+  ret i1 %or
+}
+
 ; Form a select if we know we can get replace 2 simple logic ops.
 
 define i1 @bools_multi_uses1(i1 %a, i1 %b, i1 %c) {
@@ -394,6 +406,22 @@ define i1 @bools_multi_uses1(i1 %a, i1 %b, i1 %c) {
   ret i1 %xor
 }
 
+define i1 @bools_multi_uses1_logical(i1 %a, i1 %b, i1 %c) {
+; CHECK-LABEL: @bools_multi_uses1_logical(
+; CHECK-NEXT:    [[NOT:%.*]] = xor i1 [[C:%.*]], true
+; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[NOT]], [[A:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 [[A]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[TMP1]], [[AND1]]
+; CHECK-NEXT:    ret i1 [[XOR]]
+;
+  %not = xor i1 %c, -1
+  %and1 = select i1 %not, i1 %a, i1 false
+  %and2 = select i1 %c, i1 %b, i1 false
+  %or = select i1 %and1, i1 true, i1 %and2
+  %xor = xor i1 %or, %and1
+  ret i1 %xor
+}
+
 ; Don't replace a cheap logic op with a potentially expensive select
 ; unless we can also eliminate one of the other original ops.
 
@@ -411,6 +439,20 @@ define i1 @bools_multi_uses2(i1 %a, i1 %b, i1 %c) {
   ret i1 %and3
 }
 
+define i1 @bools_multi_uses2_logical(i1 %a, i1 %b, i1 %c) {
+; CHECK-LABEL: @bools_multi_uses2_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %not = xor i1 %c, -1
+  %and1 = select i1 %not, i1 %a, i1 false
+  %and2 = select i1 %c, i1 %b, i1 false
+  %or = select i1 %and1, i1 true, i1 %and2
+  %add = add i1 %and1, %and2
+  %and3 = select i1 %or, i1 %add, i1 false
+  ret i1 %and3
+}
+
 define <4 x i1> @vec_of_bools(<4 x i1> %a, <4 x i1> %b, <4 x i1> %c) {
 ; CHECK-LABEL: @vec_of_bools(
 ; CHECK-NEXT:    [[TMP1:%.*]] = select <4 x i1> [[C:%.*]], <4 x i1> [[B:%.*]], <4 x i1> [[A:%.*]]

diff  --git a/llvm/test/Transforms/InstCombine/logical-select.ll b/llvm/test/Transforms/InstCombine/logical-select.ll
index 2f532be03fbf..5c16fc446cdd 100644
--- a/llvm/test/Transforms/InstCombine/logical-select.ll
+++ b/llvm/test/Transforms/InstCombine/logical-select.ll
@@ -376,6 +376,18 @@ define i1 @bools(i1 %a, i1 %b, i1 %c) {
   ret i1 %or
 }
 
+define i1 @bools_logical(i1 %a, i1 %b, i1 %c) {
+; CHECK-LABEL: @bools_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %not = xor i1 %c, -1
+  %and1 = select i1 %not, i1 %a, i1 false
+  %and2 = select i1 %c, i1 %b, i1 false
+  %or = select i1 %and1, i1 true, i1 %and2
+  ret i1 %or
+}
+
 ; Form a select if we know we can get replace 2 simple logic ops.
 
 define i1 @bools_multi_uses1(i1 %a, i1 %b, i1 %c) {
@@ -394,6 +406,22 @@ define i1 @bools_multi_uses1(i1 %a, i1 %b, i1 %c) {
   ret i1 %xor
 }
 
+define i1 @bools_multi_uses1_logical(i1 %a, i1 %b, i1 %c) {
+; CHECK-LABEL: @bools_multi_uses1_logical(
+; CHECK-NEXT:    [[NOT:%.*]] = xor i1 [[C:%.*]], true
+; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[NOT]], [[A:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 [[A]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[TMP1]], [[AND1]]
+; CHECK-NEXT:    ret i1 [[XOR]]
+;
+  %not = xor i1 %c, -1
+  %and1 = select i1 %not, i1 %a, i1 false
+  %and2 = select i1 %c, i1 %b, i1 false
+  %or = select i1 %and1, i1 true, i1 %and2
+  %xor = xor i1 %or, %and1
+  ret i1 %xor
+}
+
 ; Don't replace a cheap logic op with a potentially expensive select
 ; unless we can also eliminate one of the other original ops.
 
@@ -411,6 +439,20 @@ define i1 @bools_multi_uses2(i1 %a, i1 %b, i1 %c) {
   ret i1 %and3
 }
 
+define i1 @bools_multi_uses2_logical(i1 %a, i1 %b, i1 %c) {
+; CHECK-LABEL: @bools_multi_uses2_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %not = xor i1 %c, -1
+  %and1 = select i1 %not, i1 %a, i1 false
+  %and2 = select i1 %c, i1 %b, i1 false
+  %or = select i1 %and1, i1 true, i1 %and2
+  %add = add i1 %and1, %and2
+  %and3 = select i1 %or, i1 %add, i1 false
+  ret i1 %and3
+}
+
 define <4 x i1> @vec_of_bools(<4 x i1> %a, <4 x i1> %b, <4 x i1> %c) {
 ; CHECK-LABEL: @vec_of_bools(
 ; CHECK-NEXT:    [[TMP1:%.*]] = select <4 x i1> [[C:%.*]], <4 x i1> [[B:%.*]], <4 x i1> [[A:%.*]]

diff  --git a/llvm/test/Transforms/InstCombine/merge-icmp.ll b/llvm/test/Transforms/InstCombine/merge-icmp.ll
index 6a65b5befa38..e9f9bb31a0e4 100644
--- a/llvm/test/Transforms/InstCombine/merge-icmp.ll
+++ b/llvm/test/Transforms/InstCombine/merge-icmp.ll
@@ -1,6 +1,12 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt -S -instcombine < %s | FileCheck %s
 
 define i1 @test1(i16* %x) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT:    [[LOAD:%.*]] = load i16, i16* [[X:%.*]], align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i16 [[LOAD]], 17791
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
   %load = load i16, i16* %x, align 4
   %trunc = trunc i16 %load to i8
   %cmp1 = icmp eq i8 %trunc, 127
@@ -8,13 +14,29 @@ define i1 @test1(i16* %x) {
   %cmp2 = icmp eq i16 %and, 17664
   %or = and i1 %cmp1, %cmp2
   ret i1 %or
-; CHECK-LABEL: @test1(
-; CHECK-NEXT: load i16
-; CHECK-NEXT: icmp eq i16 %load, 17791
-; CHECK-NEXT: ret i1
+}
+
+define i1 @test1_logical(i16* %x) {
+; CHECK-LABEL: @test1_logical(
+; CHECK-NEXT:    [[LOAD:%.*]] = load i16, i16* [[X:%.*]], align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i16 [[LOAD]], 17791
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %load = load i16, i16* %x, align 4
+  %trunc = trunc i16 %load to i8
+  %cmp1 = icmp eq i8 %trunc, 127
+  %and = and i16 %load, -256
+  %cmp2 = icmp eq i16 %and, 17664
+  %or = select i1 %cmp1, i1 %cmp2, i1 false
+  ret i1 %or
 }
 
 define i1 @test2(i16* %x) {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT:    [[LOAD:%.*]] = load i16, i16* [[X:%.*]], align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i16 [[LOAD]], 32581
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
   %load = load i16, i16* %x, align 4
   %and = and i16 %load, -256
   %cmp1 = icmp eq i16 %and, 32512
@@ -22,8 +44,19 @@ define i1 @test2(i16* %x) {
   %cmp2 = icmp eq i8 %trunc, 69
   %or = and i1 %cmp1, %cmp2
   ret i1 %or
-; CHECK-LABEL: @test2(
-; CHECK-NEXT: load i16
-; CHECK-NEXT: icmp eq i16 %load, 32581
-; CHECK-NEXT: ret i1
+}
+
+define i1 @test2_logical(i16* %x) {
+; CHECK-LABEL: @test2_logical(
+; CHECK-NEXT:    [[LOAD:%.*]] = load i16, i16* [[X:%.*]], align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i16 [[LOAD]], 32581
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %load = load i16, i16* %x, align 4
+  %and = and i16 %load, -256
+  %cmp1 = icmp eq i16 %and, 32512
+  %trunc = trunc i16 %load to i8
+  %cmp2 = icmp eq i8 %trunc, 69
+  %or = select i1 %cmp1, i1 %cmp2, i1 false
+  ret i1 %or
 }

diff  --git a/llvm/test/Transforms/InstCombine/objsize-noverify.ll b/llvm/test/Transforms/InstCombine/objsize-noverify.ll
index 7e469bd25282..f1d0392c1845 100644
--- a/llvm/test/Transforms/InstCombine/objsize-noverify.ll
+++ b/llvm/test/Transforms/InstCombine/objsize-noverify.ll
@@ -24,6 +24,24 @@ return:
   ret i32 42
 }
 
+define i32 @PR13390_logical(i1 %bool, i8* %a) {
+entry:
+  %cond = select i1 %bool, i1 true, i1 true
+  br i1 %cond, label %return, label %xpto
+
+xpto:
+  %select = select i1 %bool, i8* %select, i8* %a
+  %select2 = select i1 %bool, i8* %a, i8* %select2
+  %0 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %select, i1 true)
+  %1 = tail call i32 @llvm.objectsize.i32.p0i8(i8* %select2, i1 true)
+  %2 = add i32 %0, %1
+; CHECK: ret i32 undef
+  ret i32 %2
+
+return:
+  ret i32 42
+}
+
 ; CHECK-LABEL: @PR13621(
 define i32 @PR13621(i1 %bool) nounwind {
 entry:
@@ -41,3 +59,20 @@ xpto:
 return:
   ret i32 7
 }
+
+define i32 @PR13621_logical(i1 %bool) nounwind {
+entry:
+  %cond = select i1 %bool, i1 true, i1 true
+  br i1 %cond, label %return, label %xpto
+
+; technically reachable, but this malformed IR may appear as a result of constant propagation
+xpto:
+  %gep2 = getelementptr i8, i8* %gep, i32 1
+  %gep = getelementptr i8, i8* %gep2, i32 1
+  %o = call i32 @llvm.objectsize.i32.p0i8(i8* %gep, i1 true)
+; CHECK: ret i32 undef
+  ret i32 %o
+
+return:
+  ret i32 7
+}

diff  --git a/llvm/test/Transforms/InstCombine/onehot_merge.ll b/llvm/test/Transforms/InstCombine/onehot_merge.ll
index d98361f1b5f6..bc0047e7a84a 100644
--- a/llvm/test/Transforms/InstCombine/onehot_merge.ll
+++ b/llvm/test/Transforms/InstCombine/onehot_merge.ll
@@ -15,6 +15,20 @@ define i1 @and_consts(i32 %k, i32 %c1, i32 %c2) {
   ret i1 %or
 }
 
+define i1 @and_consts_logical(i32 %k, i32 %c1, i32 %c2) {
+; CHECK-LABEL: @and_consts_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[K:%.*]], 12
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 12
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %t1 = and i32 4, %k
+  %t2 = icmp eq i32 %t1, 0
+  %t5 = and i32 8, %k
+  %t6 = icmp eq i32 %t5, 0
+  %or = select i1 %t2, i1 true, i1 %t6
+  ret i1 %or
+}
+
 define <2 x i1> @and_consts_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
 ; CHECK-LABEL: @and_consts_vector(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[K:%.*]], <i32 12, i32 12>
@@ -48,6 +62,25 @@ define i1 @foo1_and(i32 %k, i32 %c1, i32 %c2) {
   ret i1 %or
 }
 
+define i1 @foo1_and_logical(i32 %k, i32 %c1, i32 %c2) {
+; CHECK-LABEL: @foo1_and_logical(
+; CHECK-NEXT:    [[T:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T]], [[T4]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %t = shl i32 1, %c1
+  %t4 = shl i32 1, %c2
+  %t1 = and i32 %t, %k
+  %t2 = icmp eq i32 %t1, 0
+  %t5 = and i32 %t4, %k
+  %t6 = icmp eq i32 %t5, 0
+  %or = select i1 %t2, i1 true, i1 %t6
+  ret i1 %or
+}
+
 define <2 x i1> @foo1_and_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
 ; CHECK-LABEL: @foo1_and_vector(
 ; CHECK-NEXT:    [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
@@ -89,6 +122,27 @@ define i1 @foo1_and_commuted(i32 %k, i32 %c1, i32 %c2) {
   ret i1 %or
 }
 
+define i1 @foo1_and_commuted_logical(i32 %k, i32 %c1, i32 %c2) {
+; CHECK-LABEL: @foo1_and_commuted_logical(
+; CHECK-NEXT:    [[K2:%.*]] = mul i32 [[K:%.*]], [[K]]
+; CHECK-NEXT:    [[T:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T]], [[T4]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[K2]], [[TMP1]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %k2 = mul i32 %k, %k ; to trick the complexity sorting
+  %t = shl i32 1, %c1
+  %t4 = shl i32 1, %c2
+  %t1 = and i32 %k2, %t
+  %t2 = icmp eq i32 %t1, 0
+  %t5 = and i32 %t4, %k2
+  %t6 = icmp eq i32 %t5, 0
+  %or = select i1 %t2, i1 true, i1 %t6
+  ret i1 %or
+}
+
 define <2 x i1> @foo1_and_commuted_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
 ; CHECK-LABEL: @foo1_and_commuted_vector(
 ; CHECK-NEXT:    [[K2:%.*]] = mul <2 x i32> [[K:%.*]], [[K]]
@@ -124,6 +178,20 @@ define i1 @or_consts(i32 %k, i32 %c1, i32 %c2) {
   ret i1 %or
 }
 
+define i1 @or_consts_logical(i32 %k, i32 %c1, i32 %c2) {
+; CHECK-LABEL: @or_consts_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[K:%.*]], 12
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 12
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %t1 = and i32 4, %k
+  %t2 = icmp ne i32 %t1, 0
+  %t5 = and i32 8, %k
+  %t6 = icmp ne i32 %t5, 0
+  %or = select i1 %t2, i1 %t6, i1 false
+  ret i1 %or
+}
+
 define <2 x i1> @or_consts_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
 ; CHECK-LABEL: @or_consts_vector(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[K:%.*]], <i32 12, i32 12>
@@ -157,6 +225,25 @@ define i1 @foo1_or(i32 %k, i32 %c1, i32 %c2) {
   ret i1 %or
 }
 
+define i1 @foo1_or_logical(i32 %k, i32 %c1, i32 %c2) {
+; CHECK-LABEL: @foo1_or_logical(
+; CHECK-NEXT:    [[T:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T]], [[T4]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %t = shl i32 1, %c1
+  %t4 = shl i32 1, %c2
+  %t1 = and i32 %t, %k
+  %t2 = icmp ne i32 %t1, 0
+  %t5 = and i32 %t4, %k
+  %t6 = icmp ne i32 %t5, 0
+  %or = select i1 %t2, i1 %t6, i1 false
+  ret i1 %or
+}
+
 define <2 x i1> @foo1_or_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
 ; CHECK-LABEL: @foo1_or_vector(
 ; CHECK-NEXT:    [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
@@ -198,6 +285,27 @@ define i1 @foo1_or_commuted(i32 %k, i32 %c1, i32 %c2) {
   ret i1 %or
 }
 
+define i1 @foo1_or_commuted_logical(i32 %k, i32 %c1, i32 %c2) {
+; CHECK-LABEL: @foo1_or_commuted_logical(
+; CHECK-NEXT:    [[K2:%.*]] = mul i32 [[K:%.*]], [[K]]
+; CHECK-NEXT:    [[T:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T]], [[T4]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[K2]], [[TMP1]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %k2 = mul i32 %k, %k ; to trick the complexity sorting
+  %t = shl i32 1, %c1
+  %t4 = shl i32 1, %c2
+  %t1 = and i32 %k2, %t
+  %t2 = icmp ne i32 %t1, 0
+  %t5 = and i32 %t4, %k2
+  %t6 = icmp ne i32 %t5, 0
+  %or = select i1 %t2, i1 %t6, i1 false
+  ret i1 %or
+}
+
 define <2 x i1> @foo1_or_commuted_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
 ; CHECK-LABEL: @foo1_or_commuted_vector(
 ; CHECK-NEXT:    [[K2:%.*]] = mul <2 x i32> [[K:%.*]], [[K]]
@@ -238,6 +346,25 @@ define i1 @foo1_and_signbit_lshr(i32 %k, i32 %c1, i32 %c2) {
   ret i1 %or
 }
 
+define i1 @foo1_and_signbit_lshr_logical(i32 %k, i32 %c1, i32 %c2) {
+; CHECK-LABEL: @foo1_and_signbit_lshr_logical(
+; CHECK-NEXT:    [[T:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = lshr i32 -2147483648, [[C2:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T]], [[T4]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %t = shl i32 1, %c1
+  %t4 = lshr i32 -2147483648, %c2
+  %t1 = and i32 %t, %k
+  %t2 = icmp eq i32 %t1, 0
+  %t5 = and i32 %t4, %k
+  %t6 = icmp eq i32 %t5, 0
+  %or = select i1 %t2, i1 true, i1 %t6
+  ret i1 %or
+}
+
 define <2 x i1> @foo1_and_signbit_lshr_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
 ; CHECK-LABEL: @foo1_and_signbit_lshr_vector(
 ; CHECK-NEXT:    [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
@@ -276,6 +403,25 @@ define i1 @foo1_or_signbit_lshr(i32 %k, i32 %c1, i32 %c2) {
   ret i1 %or
 }
 
+define i1 @foo1_or_signbit_lshr_logical(i32 %k, i32 %c1, i32 %c2) {
+; CHECK-LABEL: @foo1_or_signbit_lshr_logical(
+; CHECK-NEXT:    [[T:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = lshr i32 -2147483648, [[C2:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T]], [[T4]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %t = shl i32 1, %c1
+  %t4 = lshr i32 -2147483648, %c2
+  %t1 = and i32 %t, %k
+  %t2 = icmp ne i32 %t1, 0
+  %t5 = and i32 %t4, %k
+  %t6 = icmp ne i32 %t5, 0
+  %or = select i1 %t2, i1 %t6, i1 false
+  ret i1 %or
+}
+
 define <2 x i1> @foo1_or_signbit_lshr_vector(<2 x i32> %k, <2 x i32> %c1, <2 x i32> %c2) {
 ; CHECK-LABEL: @foo1_or_signbit_lshr_vector(
 ; CHECK-NEXT:    [[T:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[C1:%.*]]
@@ -315,6 +461,25 @@ define i1 @foo1_and_signbit_lshr_without_shifting_signbit(i32 %k, i32 %c1, i32 %
   ret i1 %or
 }
 
+define i1 @foo1_and_signbit_lshr_without_shifting_signbit_logical(i32 %k, i32 %c1, i32 %c2) {
+; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = icmp sgt i32 [[T3]], -1
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %t0 = shl i32 1, %c1
+  %t1 = and i32 %t0, %k
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = shl i32 %k, %c2
+  %t4 = icmp sgt i32 %t3, -1
+  %or = select i1 %t2, i1 true, i1 %t4
+  ret i1 %or
+}
+
 define i1 @foo1_or_signbit_lshr_without_shifting_signbit(i32 %k, i32 %c1, i32 %c2) {
 ; CHECK-LABEL: @foo1_or_signbit_lshr_without_shifting_signbit(
 ; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
@@ -334,6 +499,25 @@ define i1 @foo1_or_signbit_lshr_without_shifting_signbit(i32 %k, i32 %c1, i32 %c
   ret i1 %or
 }
 
+define i1 @foo1_or_signbit_lshr_without_shifting_signbit_logical(i32 %k, i32 %c1, i32 %c2) {
+; CHECK-LABEL: @foo1_or_signbit_lshr_without_shifting_signbit_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = icmp ne i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = icmp slt i32 [[T3]], 0
+; CHECK-NEXT:    [[OR:%.*]] = and i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %t0 = shl i32 1, %c1
+  %t1 = and i32 %t0, %k
+  %t2 = icmp ne i32 %t1, 0
+  %t3 = shl i32 %k, %c2
+  %t4 = icmp slt i32 %t3, 0
+  %or = select i1 %t2, i1 %t4, i1 false
+  ret i1 %or
+}
+
 ; Shift-of-signbit replaced with 'icmp s*' for both sides
 define i1 @foo1_and_signbit_lshr_without_shifting_signbit_both_sides(i32 %k, i32 %c1, i32 %c2) {
 ; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_both_sides(
@@ -351,6 +535,22 @@ define i1 @foo1_and_signbit_lshr_without_shifting_signbit_both_sides(i32 %k, i32
   ret i1 %or
 }
 
+define i1 @foo1_and_signbit_lshr_without_shifting_signbit_both_sides_logical(i32 %k, i32 %c1, i32 %c2) {
+; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_both_sides_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 [[K:%.*]], [[C1:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = shl i32 [[K]], [[C2:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[T0]], [[T2]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], -1
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %t0 = shl i32 %k, %c1
+  %t1 = icmp sgt i32 %t0, -1
+  %t2 = shl i32 %k, %c2
+  %t3 = icmp sgt i32 %t2, -1
+  %or = select i1 %t1, i1 true, i1 %t3
+  ret i1 %or
+}
+
 define i1 @foo1_or_signbit_lshr_without_shifting_signbit_both_sides(i32 %k, i32 %c1, i32 %c2) {
 ; CHECK-LABEL: @foo1_or_signbit_lshr_without_shifting_signbit_both_sides(
 ; CHECK-NEXT:    [[T0:%.*]] = shl i32 [[K:%.*]], [[C1:%.*]]
@@ -367,6 +567,22 @@ define i1 @foo1_or_signbit_lshr_without_shifting_signbit_both_sides(i32 %k, i32
   ret i1 %or
 }
 
+define i1 @foo1_or_signbit_lshr_without_shifting_signbit_both_sides_logical(i32 %k, i32 %c1, i32 %c2) {
+; CHECK-LABEL: @foo1_or_signbit_lshr_without_shifting_signbit_both_sides_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 [[K:%.*]], [[C1:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = shl i32 [[K]], [[C2:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[T0]], [[T2]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 0
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %t0 = shl i32 %k, %c1
+  %t1 = icmp slt i32 %t0, 0
+  %t2 = shl i32 %k, %c2
+  %t3 = icmp slt i32 %t2, 0
+  %or = select i1 %t1, i1 %t3, i1 false
+  ret i1 %or
+}
+
 ; Extra use
 
 ; Expect to fold
@@ -391,6 +607,27 @@ define i1 @foo1_and_extra_use_shl(i32 %k, i32 %c1, i32 %c2, i32* %p) {
   ret i1 %or
 }
 
+define i1 @foo1_and_extra_use_shl_logical(i32 %k, i32 %c1, i32 %c2, i32* %p) {
+; CHECK-LABEL: @foo1_and_extra_use_shl_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    store i32 [[T0]], i32* [[P:%.*]], align 4
+; CHECK-NEXT:    [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %t0 = shl i32 1, %c1
+  store i32 %t0, i32* %p  ; extra use of shl
+  %t1 = shl i32 1, %c2
+  %t2 = and i32 %t0, %k
+  %t3 = icmp eq i32 %t2, 0
+  %t4 = and i32 %t1, %k
+  %t5 = icmp eq i32 %t4, 0
+  %or = select i1 %t3, i1 true, i1 %t5
+  ret i1 %or
+}
+
 ; Should not fold
 define i1 @foo1_and_extra_use_and(i32 %k, i32 %c1, i32 %c2, i32* %p) {
 ; CHECK-LABEL: @foo1_and_extra_use_and(
@@ -414,6 +651,28 @@ define i1 @foo1_and_extra_use_and(i32 %k, i32 %c1, i32 %c2, i32* %p) {
   ret i1 %or
 }
 
+define i1 @foo1_and_extra_use_and_logical(i32 %k, i32 %c1, i32 %c2, i32* %p) {
+; CHECK-LABEL: @foo1_and_extra_use_and_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T0]], [[K:%.*]]
+; CHECK-NEXT:    store i32 [[T2]], i32* [[P:%.*]], align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %t0 = shl i32 1, %c1
+  %t1 = shl i32 1, %c2
+  %t2 = and i32 %t0, %k
+  store i32 %t2, i32* %p  ; extra use of and
+  %t3 = icmp eq i32 %t2, 0
+  %t4 = and i32 %t1, %k
+  %t5 = icmp eq i32 %t4, 0
+  %or = select i1 %t3, i1 true, i1 %t5
+  ret i1 %or
+}
+
 ; Should not fold
 define i1 @foo1_and_extra_use_cmp(i32 %k, i32 %c1, i32 %c2, i1* %p) {
 ; CHECK-LABEL: @foo1_and_extra_use_cmp(
@@ -438,6 +697,29 @@ define i1 @foo1_and_extra_use_cmp(i32 %k, i32 %c1, i32 %c2, i1* %p) {
   ret i1 %or
 }
 
+define i1 @foo1_and_extra_use_cmp_logical(i32 %k, i32 %c1, i32 %c2, i1* %p) {
+; CHECK-LABEL: @foo1_and_extra_use_cmp_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T0]], [[K:%.*]]
+; CHECK-NEXT:    [[T3:%.*]] = icmp eq i32 [[T2]], 0
+; CHECK-NEXT:    store i1 [[T3]], i1* [[P:%.*]], align 1
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %t0 = shl i32 1, %c1
+  %t1 = shl i32 1, %c2
+  %t2 = and i32 %t0, %k
+  %t3 = icmp eq i32 %t2, 0
+  store i1 %t3, i1* %p  ; extra use of cmp
+  %t4 = and i32 %t1, %k
+  %t5 = icmp eq i32 %t4, 0
+  %or = select i1 %t3, i1 true, i1 %t5
+  ret i1 %or
+}
+
 ; Expect to fold
 define i1 @foo1_and_extra_use_shl2(i32 %k, i32 %c1, i32 %c2, i32* %p) {
 ; CHECK-LABEL: @foo1_and_extra_use_shl2(
@@ -460,6 +742,27 @@ define i1 @foo1_and_extra_use_shl2(i32 %k, i32 %c1, i32 %c2, i32* %p) {
   ret i1 %or
 }
 
+define i1 @foo1_and_extra_use_shl2_logical(i32 %k, i32 %c1, i32 %c2, i32* %p) {
+; CHECK-LABEL: @foo1_and_extra_use_shl2_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT:    store i32 [[T1]], i32* [[P:%.*]], align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K:%.*]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %t0 = shl i32 1, %c1
+  %t1 = shl i32 1, %c2
+  store i32 %t1, i32* %p  ; extra use of shl
+  %t2 = and i32 %t0, %k
+  %t3 = icmp eq i32 %t2, 0
+  %t4 = and i32 %t1, %k
+  %t5 = icmp eq i32 %t4, 0
+  %or = select i1 %t3, i1 true, i1 %t5
+  ret i1 %or
+}
+
 ; Should not fold
 define i1 @foo1_and_extra_use_and2(i32 %k, i32 %c1, i32 %c2, i32* %p) {
 ; CHECK-LABEL: @foo1_and_extra_use_and2(
@@ -483,6 +786,28 @@ define i1 @foo1_and_extra_use_and2(i32 %k, i32 %c1, i32 %c2, i32* %p) {
   ret i1 %or
 }
 
+define i1 @foo1_and_extra_use_and2_logical(i32 %k, i32 %c1, i32 %c2, i32* %p) {
+; CHECK-LABEL: @foo1_and_extra_use_and2_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = and i32 [[T1]], [[K:%.*]]
+; CHECK-NEXT:    store i32 [[T4]], i32* [[P:%.*]], align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %t0 = shl i32 1, %c1
+  %t1 = shl i32 1, %c2
+  %t2 = and i32 %t0, %k
+  %t3 = icmp eq i32 %t2, 0
+  %t4 = and i32 %t1, %k
+  store i32 %t4, i32* %p  ; extra use of and
+  %t5 = icmp eq i32 %t4, 0
+  %or = select i1 %t3, i1 true, i1 %t5
+  ret i1 %or
+}
+
 ; Should not fold
 define i1 @foo1_and_extra_use_cmp2(i32 %k, i32 %c1, i32 %c2, i1* %p) {
 ; CHECK-LABEL: @foo1_and_extra_use_cmp2(
@@ -507,6 +832,29 @@ define i1 @foo1_and_extra_use_cmp2(i32 %k, i32 %c1, i32 %c2, i1* %p) {
   ret i1 %or
 }
 
+define i1 @foo1_and_extra_use_cmp2_logical(i32 %k, i32 %c1, i32 %c2, i1* %p) {
+; CHECK-LABEL: @foo1_and_extra_use_cmp2_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = shl i32 1, [[C2:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = and i32 [[T1]], [[K:%.*]]
+; CHECK-NEXT:    [[T5:%.*]] = icmp eq i32 [[T4]], 0
+; CHECK-NEXT:    store i1 [[T5]], i1* [[P:%.*]], align 1
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[T0]], [[T1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[K]]
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %t0 = shl i32 1, %c1
+  %t1 = shl i32 1, %c2
+  %t2 = and i32 %t0, %k
+  %t3 = icmp eq i32 %t2, 0
+  %t4 = and i32 %t1, %k
+  %t5 = icmp eq i32 %t4, 0
+  store i1 %t5, i1* %p  ; extra use of cmp
+  %or = select i1 %t3, i1 true, i1 %t5
+  ret i1 %or
+}
+
 ; Shift-of-signbit replaced with 'icmp s*'
 ; Expect to fold
 define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl1(i32 %k, i32 %c1, i32 %c2, i32* %p) {
@@ -530,6 +878,27 @@ define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl1(i32 %k,
   ret i1 %or
 }
 
+define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl1_logical(i32 %k, i32 %c1, i32 %c2, i32* %p) {
+; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl1_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    store i32 [[T0]], i32* [[P:%.*]], align 4
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = icmp sgt i32 [[T3]], -1
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %t0 = shl i32 1, %c1
+  store i32 %t0, i32* %p  ; extra use of shl
+  %t1 = and i32 %t0, %k
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = shl i32 %k, %c2
+  %t4 = icmp sgt i32 %t3, -1
+  %or = select i1 %t2, i1 true, i1 %t4
+  ret i1 %or
+}
+
 ; Not fold
 define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_and(i32 %k, i32 %c1, i32 %c2, i32* %p) {
 ; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_and(
@@ -552,6 +921,27 @@ define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_and(i32 %k,
   ret i1 %or
 }
 
+define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_and_logical(i32 %k, i32 %c1, i32 %c2, i32* %p) {
+; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_and_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
+; CHECK-NEXT:    store i32 [[T1]], i32* [[P:%.*]], align 4
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = icmp sgt i32 [[T3]], -1
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %t0 = shl i32 1, %c1
+  %t1 = and i32 %t0, %k
+  store i32 %t1, i32* %p  ; extra use of and
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = shl i32 %k, %c2
+  %t4 = icmp sgt i32 %t3, -1
+  %or = select i1 %t2, i1 true, i1 %t4
+  ret i1 %or
+}
+
 ; Not fold
 define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp1(i32 %k, i32 %c1, i32 %c2, i1* %p) {
 ; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp1(
@@ -574,6 +964,27 @@ define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp1(i32 %k,
   ret i1 %or
 }
 
+define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp1_logical(i32 %k, i32 %c1, i32 %c2, i1* %p) {
+; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp1_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    store i1 [[T2]], i1* [[P:%.*]], align 1
+; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = icmp sgt i32 [[T3]], -1
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %t0 = shl i32 1, %c1
+  %t1 = and i32 %t0, %k
+  %t2 = icmp eq i32 %t1, 0
+  store i1 %t2, i1* %p  ; extra use of cmp
+  %t3 = shl i32 %k, %c2
+  %t4 = icmp sgt i32 %t3, -1
+  %or = select i1 %t2, i1 true, i1 %t4
+  ret i1 %or
+}
+
 ; Not fold
 define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl2(i32 %k, i32 %c1, i32 %c2, i32* %p) {
 ; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl2(
@@ -596,6 +1007,27 @@ define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl2(i32 %k,
   ret i1 %or
 }
 
+define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl2_logical(i32 %k, i32 %c1, i32 %c2, i32* %p) {
+; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_shl2_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
+; CHECK-NEXT:    store i32 [[T3]], i32* [[P:%.*]], align 4
+; CHECK-NEXT:    [[T4:%.*]] = icmp sgt i32 [[T3]], -1
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %t0 = shl i32 1, %c1
+  %t1 = and i32 %t0, %k
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = shl i32 %k, %c2
+  store i32 %t3, i32* %p  ; extra use of shl
+  %t4 = icmp sgt i32 %t3, -1
+  %or = select i1 %t2, i1 true, i1 %t4
+  ret i1 %or
+}
+
 ; Not fold
 define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp2(i32 %k, i32 %c1, i32 %c2, i1* %p) {
 ; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp2(
@@ -618,6 +1050,27 @@ define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp2(i32 %k,
   ret i1 %or
 }
 
+define i1 @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp2_logical(i32 %k, i32 %c1, i32 %c2, i1* %p) {
+; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_extra_use_cmp2_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 1, [[C1:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = icmp sgt i32 [[T3]], -1
+; CHECK-NEXT:    store i1 [[T4]], i1* [[P:%.*]], align 1
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %t0 = shl i32 1, %c1
+  %t1 = and i32 %t0, %k
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = shl i32 %k, %c2
+  %t4 = icmp sgt i32 %t3, -1
+  store i1 %t4, i1* %p  ; extra use of cmp
+  %or = select i1 %t2, i1 true, i1 %t4
+  ret i1 %or
+}
+
 ; Negative tests
 
 ; This test checks that we are not creating additional shift instruction when fold fails.
@@ -639,3 +1092,22 @@ define i1 @foo1_and_signbit_lshr_without_shifting_signbit_not_pwr2(i32 %k, i32 %
   %or = or i1 %t2, %t4
   ret i1 %or
 }
+
+define i1 @foo1_and_signbit_lshr_without_shifting_signbit_not_pwr2_logical(i32 %k, i32 %c1, i32 %c2) {
+; CHECK-LABEL: @foo1_and_signbit_lshr_without_shifting_signbit_not_pwr2_logical(
+; CHECK-NEXT:    [[T0:%.*]] = shl i32 3, [[C1:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[T0]], [[K:%.*]]
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[K]], [[C2:%.*]]
+; CHECK-NEXT:    [[T4:%.*]] = icmp sgt i32 [[T3]], -1
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %t0 = shl i32 3, %c1
+  %t1 = and i32 %t0, %k
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = shl i32 %k, %c2
+  %t4 = icmp sgt i32 %t3, -1
+  %or = select i1 %t2, i1 true, i1 %t4
+  ret i1 %or
+}

diff  --git a/llvm/test/Transforms/InstCombine/or-fcmp.ll b/llvm/test/Transforms/InstCombine/or-fcmp.ll
index 10ac51ae32bc..da12ddf668c4 100644
--- a/llvm/test/Transforms/InstCombine/or-fcmp.ll
+++ b/llvm/test/Transforms/InstCombine/or-fcmp.ll
@@ -12,6 +12,17 @@ define i1 @PR1738(double %x, double %y) {
   ret i1 %or
 }
 
+define i1 @PR1738_logical(double %x, double %y) {
+; CHECK-LABEL: @PR1738_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp1 = fcmp uno double %x, 0.0
+  %cmp2 = fcmp uno double %y, 0.0
+  %or = select i1 %cmp1, i1 true, i1 %cmp2
+  ret i1 %or
+}
+
 define <2 x i1> @PR1738_vec_undef(<2 x double> %x, <2 x double> %y) {
 ; CHECK-LABEL: @PR1738_vec_undef(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno <2 x double> [[X:%.*]], [[Y:%.*]]
@@ -38,6 +49,21 @@ define i1 @PR41069(double %a, double %b, double %c, double %d) {
   ret i1 %r
 }
 
+define i1 @PR41069_logical(double %a, double %b, double %c, double %d) {
+; CHECK-LABEL: @PR41069_logical(
+; CHECK-NEXT:    [[UNO1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[D:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[TMP1]], [[UNO1]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %uno1 = fcmp uno double %a, %b
+  %uno2 = fcmp uno double %c, 0.0
+  %or = select i1 %uno1, i1 true, i1 %uno2
+  %uno3 = fcmp uno double %d, 0.0
+  %r = select i1 %or, i1 true, i1 %uno3
+  ret i1 %r
+}
+
 define i1 @PR41069_commute(double %a, double %b, double %c, double %d) {
 ; CHECK-LABEL: @PR41069_commute(
 ; CHECK-NEXT:    [[UNO1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -53,6 +79,21 @@ define i1 @PR41069_commute(double %a, double %b, double %c, double %d) {
   ret i1 %r
 }
 
+define i1 @PR41069_commute_logical(double %a, double %b, double %c, double %d) {
+; CHECK-LABEL: @PR41069_commute_logical(
+; CHECK-NEXT:    [[UNO1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[D:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[TMP1]], [[UNO1]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %uno1 = fcmp uno double %a, %b
+  %uno2 = fcmp uno double %c, 0.0
+  %or = select i1 %uno1, i1 true, i1 %uno2
+  %uno3 = fcmp uno double %d, 0.0
+  %r = select i1 %uno3, i1 true, i1 %or
+  ret i1 %r
+}
+
 define <2 x i1> @PR41069_vec(<2 x i1> %z, <2 x float> %c, <2 x float> %d) {
 ; CHECK-LABEL: @PR41069_vec(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno <2 x float> [[D:%.*]], [[C:%.*]]
@@ -90,6 +131,17 @@ define i1 @fcmp_uno_nonzero(float %x, float %y) {
   ret i1 %or
 }
 
+define i1 @fcmp_uno_nonzero_logical(float %x, float %y) {
+; CHECK-LABEL: @fcmp_uno_nonzero_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno float [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp1 = fcmp uno float %x, 1.0
+  %cmp2 = fcmp uno float %y, 2.0
+  %or = select i1 %cmp1, i1 true, i1 %cmp2
+  ret i1 %or
+}
+
 define <3 x i1> @fcmp_uno_nonzero_vec(<3 x float> %x, <3 x float> %y) {
 ; CHECK-LABEL: @fcmp_uno_nonzero_vec(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno <3 x float> [[X:%.*]], [[Y:%.*]]
@@ -111,6 +163,16 @@ define i1 @auto_gen_0(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_0_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_0_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %cmp = fcmp false double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_1(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_1(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
@@ -122,6 +184,17 @@ define i1 @auto_gen_1(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_1_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_1_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = fcmp oeq double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_2(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_2(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
@@ -133,6 +206,17 @@ define i1 @auto_gen_2(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_2_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_2_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oeq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp oeq double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_3(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_3(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -144,6 +228,17 @@ define i1 @auto_gen_3(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_3_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_3_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = fcmp ogt double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_4(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_4(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
@@ -155,6 +250,17 @@ define i1 @auto_gen_4(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_4_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_4_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ogt double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_5(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_5(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
@@ -166,6 +272,17 @@ define i1 @auto_gen_5(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_5_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_5_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ogt double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_6(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_6(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
@@ -177,6 +294,17 @@ define i1 @auto_gen_6(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_6_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_6_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = fcmp oge double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_7(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_7(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
@@ -188,6 +316,17 @@ define i1 @auto_gen_7(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_7_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_7_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp oge double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_8(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_8(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
@@ -199,6 +338,17 @@ define i1 @auto_gen_8(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_8_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_8_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp oge double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_9(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_9(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
@@ -210,6 +360,17 @@ define i1 @auto_gen_9(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_9_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_9_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp oge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp oge double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_10(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_10(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -221,6 +382,17 @@ define i1 @auto_gen_10(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_10_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_10_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = fcmp olt double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_11(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_11(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
@@ -232,6 +404,17 @@ define i1 @auto_gen_11(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_11_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_11_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp olt double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_12(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_12(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
@@ -243,6 +426,17 @@ define i1 @auto_gen_12(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_12_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_12_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp olt double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_13(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_13(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
@@ -254,6 +448,17 @@ define i1 @auto_gen_13(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_13_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_13_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp olt double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_14(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_14(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
@@ -265,6 +470,17 @@ define i1 @auto_gen_14(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_14_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_14_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp olt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp olt double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_15(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_15(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
@@ -276,6 +492,17 @@ define i1 @auto_gen_15(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_15_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_15_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = fcmp ole double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_16(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_16(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
@@ -287,6 +514,17 @@ define i1 @auto_gen_16(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_16_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_16_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ole double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_17(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_17(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
@@ -298,6 +536,17 @@ define i1 @auto_gen_17(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_17_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_17_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ole double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_18(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_18(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
@@ -309,6 +558,17 @@ define i1 @auto_gen_18(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_18_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_18_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ole double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_19(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_19(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
@@ -320,6 +580,17 @@ define i1 @auto_gen_19(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_19_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_19_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ole double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_20(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_20(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
@@ -331,6 +602,17 @@ define i1 @auto_gen_20(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_20_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_20_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ole double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ole double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_21(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_21(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
@@ -342,6 +624,17 @@ define i1 @auto_gen_21(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_21_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_21_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = fcmp one double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_22(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_22(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
@@ -353,6 +646,17 @@ define i1 @auto_gen_22(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_22_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_22_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp one double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_23(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_23(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
@@ -364,6 +668,17 @@ define i1 @auto_gen_23(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_23_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_23_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp one double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_24(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_24(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
@@ -375,6 +690,17 @@ define i1 @auto_gen_24(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_24_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_24_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp one double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_25(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_25(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
@@ -386,6 +712,17 @@ define i1 @auto_gen_25(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_25_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_25_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp one double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_26(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_26(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
@@ -397,6 +734,17 @@ define i1 @auto_gen_26(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_26_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_26_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp one double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_27(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_27(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
@@ -408,9 +756,20 @@ define i1 @auto_gen_27(double %a, double %b) {
   ret i1 %retval
 }
 
-define i1 @auto_gen_28(double %a, double %b) {
-; CHECK-LABEL: @auto_gen_28(
-; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+define i1 @auto_gen_27_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_27_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp one double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp one double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
+define i1 @auto_gen_28(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_28(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %cmp = fcmp ord double %a, %b
@@ -419,6 +778,17 @@ define i1 @auto_gen_28(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_28_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_28_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_29(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_29(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
@@ -430,6 +800,17 @@ define i1 @auto_gen_29(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_29_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_29_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_30(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_30(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
@@ -441,6 +822,17 @@ define i1 @auto_gen_30(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_30_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_30_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_31(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_31(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
@@ -452,6 +844,17 @@ define i1 @auto_gen_31(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_31_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_31_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_32(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_32(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
@@ -463,6 +866,17 @@ define i1 @auto_gen_32(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_32_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_32_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_33(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_33(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
@@ -474,6 +888,17 @@ define i1 @auto_gen_33(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_33_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_33_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_34(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_34(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
@@ -485,6 +910,17 @@ define i1 @auto_gen_34(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_34_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_34_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_35(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_35(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
@@ -496,6 +932,17 @@ define i1 @auto_gen_35(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_35_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_35_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ord double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ord double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_36(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_36(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
@@ -507,6 +954,17 @@ define i1 @auto_gen_36(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_36_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_36_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_37(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_37(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
@@ -518,6 +976,17 @@ define i1 @auto_gen_37(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_37_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_37_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_38(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_38(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -529,6 +998,17 @@ define i1 @auto_gen_38(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_38_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_38_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_39(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_39(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -540,6 +1020,17 @@ define i1 @auto_gen_39(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_39_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_39_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_40(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_40(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
@@ -551,6 +1042,17 @@ define i1 @auto_gen_40(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_40_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_40_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_41(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_41(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
@@ -562,6 +1064,17 @@ define i1 @auto_gen_41(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_41_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_41_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_42(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_42(
 ; CHECK-NEXT:    ret i1 true
@@ -572,6 +1085,16 @@ define i1 @auto_gen_42(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_42_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_42_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_43(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_43(
 ; CHECK-NEXT:    ret i1 true
@@ -582,6 +1105,16 @@ define i1 @auto_gen_43(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_43_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_43_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_44(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_44(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
@@ -593,6 +1126,17 @@ define i1 @auto_gen_44(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_44_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_44_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ueq double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_45(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_45(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
@@ -604,6 +1148,17 @@ define i1 @auto_gen_45(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_45_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_45_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_46(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_46(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -615,6 +1170,17 @@ define i1 @auto_gen_46(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_46_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_46_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_47(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_47(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
@@ -626,6 +1192,17 @@ define i1 @auto_gen_47(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_47_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_47_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_48(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_48(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -637,6 +1214,17 @@ define i1 @auto_gen_48(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_48_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_48_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_49(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_49(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
@@ -648,6 +1236,17 @@ define i1 @auto_gen_49(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_49_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_49_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_50(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_50(
 ; CHECK-NEXT:    ret i1 true
@@ -658,6 +1257,16 @@ define i1 @auto_gen_50(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_50_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_50_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_51(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_51(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
@@ -669,6 +1278,17 @@ define i1 @auto_gen_51(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_51_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_51_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_52(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_52(
 ; CHECK-NEXT:    ret i1 true
@@ -679,6 +1299,16 @@ define i1 @auto_gen_52(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_52_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_52_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_53(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_53(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -690,6 +1320,17 @@ define i1 @auto_gen_53(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_53_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_53_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_54(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_54(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
@@ -701,6 +1342,17 @@ define i1 @auto_gen_54(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_54_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_54_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ugt double %a, %b
+  %cmp1 = fcmp ugt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_55(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_55(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -712,6 +1364,17 @@ define i1 @auto_gen_55(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_55_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_55_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_56(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_56(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -723,6 +1386,17 @@ define i1 @auto_gen_56(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_56_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_56_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_57(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_57(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -734,6 +1408,17 @@ define i1 @auto_gen_57(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_57_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_57_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_58(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_58(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -745,6 +1430,17 @@ define i1 @auto_gen_58(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_58_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_58_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_59(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_59(
 ; CHECK-NEXT:    ret i1 true
@@ -755,6 +1451,16 @@ define i1 @auto_gen_59(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_59_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_59_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_60(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_60(
 ; CHECK-NEXT:    ret i1 true
@@ -765,6 +1471,16 @@ define i1 @auto_gen_60(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_60_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_60_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_61(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_61(
 ; CHECK-NEXT:    ret i1 true
@@ -775,6 +1491,16 @@ define i1 @auto_gen_61(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_61_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_61_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_62(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_62(
 ; CHECK-NEXT:    ret i1 true
@@ -785,6 +1511,16 @@ define i1 @auto_gen_62(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_62_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_62_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_63(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_63(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -796,6 +1532,17 @@ define i1 @auto_gen_63(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_63_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_63_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_64(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_64(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -807,6 +1554,17 @@ define i1 @auto_gen_64(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_64_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_64_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp ugt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_65(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_65(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -818,6 +1576,17 @@ define i1 @auto_gen_65(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_65_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_65_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uge double %a, %b
+  %cmp1 = fcmp uge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_66(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_66(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
@@ -829,25 +1598,58 @@ define i1 @auto_gen_66(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_66_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_66_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_67(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_67(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %cmp = fcmp ult double %a, %b
-  %cmp1 = fcmp oeq double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = or i1 %cmp, %cmp1
+  ret i1 %retval
+}
+
+define i1 @auto_gen_67_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_67_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
+define i1 @auto_gen_68(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_68(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
   %retval = or i1 %cmp, %cmp1
   ret i1 %retval
 }
 
-define i1 @auto_gen_68(double %a, double %b) {
-; CHECK-LABEL: @auto_gen_68(
+define i1 @auto_gen_68_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_68_logical(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %cmp = fcmp ult double %a, %b
   %cmp1 = fcmp ogt double %a, %b
-  %retval = or i1 %cmp, %cmp1
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
   ret i1 %retval
 }
 
@@ -861,6 +1663,16 @@ define i1 @auto_gen_69(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_69_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_69_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_70(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_70(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
@@ -872,6 +1684,17 @@ define i1 @auto_gen_70(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_70_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_70_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_71(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_71(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
@@ -883,6 +1706,17 @@ define i1 @auto_gen_71(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_71_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_71_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_72(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_72(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
@@ -894,6 +1728,17 @@ define i1 @auto_gen_72(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_72_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_72_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_73(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_73(
 ; CHECK-NEXT:    ret i1 true
@@ -904,6 +1749,16 @@ define i1 @auto_gen_73(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_73_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_73_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_74(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_74(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
@@ -915,6 +1770,17 @@ define i1 @auto_gen_74(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_74_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_74_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_75(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_75(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
@@ -926,6 +1792,17 @@ define i1 @auto_gen_75(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_75_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_75_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp ugt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_76(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_76(
 ; CHECK-NEXT:    ret i1 true
@@ -936,6 +1813,16 @@ define i1 @auto_gen_76(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_76_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_76_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp uge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_77(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_77(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
@@ -947,6 +1834,17 @@ define i1 @auto_gen_77(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_77_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_77_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ult double %a, %b
+  %cmp1 = fcmp ult double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_78(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_78(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
@@ -958,6 +1856,17 @@ define i1 @auto_gen_78(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_78_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_78_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_79(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_79(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
@@ -969,6 +1878,17 @@ define i1 @auto_gen_79(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_79_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_79_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_80(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_80(
 ; CHECK-NEXT:    ret i1 true
@@ -979,6 +1899,16 @@ define i1 @auto_gen_80(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_80_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_80_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_81(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_81(
 ; CHECK-NEXT:    ret i1 true
@@ -989,6 +1919,16 @@ define i1 @auto_gen_81(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_81_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_81_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_82(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_82(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
@@ -1000,6 +1940,17 @@ define i1 @auto_gen_82(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_82_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_82_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_83(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_83(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
@@ -1011,6 +1962,17 @@ define i1 @auto_gen_83(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_83_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_83_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_84(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_84(
 ; CHECK-NEXT:    ret i1 true
@@ -1021,6 +1983,16 @@ define i1 @auto_gen_84(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_84_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_84_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_85(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_85(
 ; CHECK-NEXT:    ret i1 true
@@ -1031,6 +2003,16 @@ define i1 @auto_gen_85(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_85_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_85_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_86(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_86(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
@@ -1042,6 +2024,17 @@ define i1 @auto_gen_86(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_86_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_86_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_87(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_87(
 ; CHECK-NEXT:    ret i1 true
@@ -1052,6 +2045,16 @@ define i1 @auto_gen_87(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_87_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_87_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp ugt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_88(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_88(
 ; CHECK-NEXT:    ret i1 true
@@ -1062,6 +2065,16 @@ define i1 @auto_gen_88(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_88_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_88_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp uge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_89(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_89(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
@@ -1073,6 +2086,17 @@ define i1 @auto_gen_89(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_89_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_89_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp ult double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_90(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_90(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
@@ -1084,6 +2108,17 @@ define i1 @auto_gen_90(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_90_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_90_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp ule double %a, %b
+  %cmp1 = fcmp ule double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_91(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_91(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
@@ -1095,6 +2130,17 @@ define i1 @auto_gen_91(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_91_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_91_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_92(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_92(
 ; CHECK-NEXT:    ret i1 true
@@ -1105,6 +2151,16 @@ define i1 @auto_gen_92(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_92_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_92_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_93(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_93(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
@@ -1116,6 +2172,17 @@ define i1 @auto_gen_93(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_93_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_93_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_94(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_94(
 ; CHECK-NEXT:    ret i1 true
@@ -1126,6 +2193,16 @@ define i1 @auto_gen_94(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_94_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_94_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_95(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_95(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
@@ -1137,6 +2214,17 @@ define i1 @auto_gen_95(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_95_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_95_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_96(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_96(
 ; CHECK-NEXT:    ret i1 true
@@ -1147,6 +2235,16 @@ define i1 @auto_gen_96(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_96_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_96_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_97(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_97(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
@@ -1158,6 +2256,17 @@ define i1 @auto_gen_97(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_97_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_97_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_98(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_98(
 ; CHECK-NEXT:    ret i1 true
@@ -1168,6 +2277,16 @@ define i1 @auto_gen_98(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_98_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_98_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_99(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_99(
 ; CHECK-NEXT:    ret i1 true
@@ -1178,6 +2297,16 @@ define i1 @auto_gen_99(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_99_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_99_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_100(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_100(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
@@ -1189,13 +2318,34 @@ define i1 @auto_gen_100(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_100_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_100_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp ugt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_101(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_101(
 ; CHECK-NEXT:    ret i1 true
 ;
   %cmp = fcmp une double %a, %b
   %cmp1 = fcmp uge double %a, %b
-  %retval = or i1 %cmp, %cmp1
+  %retval = or i1 %cmp, %cmp1
+  ret i1 %retval
+}
+
+define i1 @auto_gen_101_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_101_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp uge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
   ret i1 %retval
 }
 
@@ -1210,6 +2360,17 @@ define i1 @auto_gen_102(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_102_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_102_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp ult double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_103(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_103(
 ; CHECK-NEXT:    ret i1 true
@@ -1220,6 +2381,16 @@ define i1 @auto_gen_103(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_103_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_103_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp ule double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_104(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_104(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
@@ -1231,6 +2402,17 @@ define i1 @auto_gen_104(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_104_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_104_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp une double %a, %b
+  %cmp1 = fcmp une double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_105(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_105(
 ; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -1242,6 +2424,17 @@ define i1 @auto_gen_105(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_105_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_105_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_106(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_106(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
@@ -1253,6 +2446,17 @@ define i1 @auto_gen_106(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_106_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_106_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_107(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_107(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
@@ -1264,6 +2468,17 @@ define i1 @auto_gen_107(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_107_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_107_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_108(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_108(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -1275,6 +2490,17 @@ define i1 @auto_gen_108(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_108_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_108_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_109(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_109(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
@@ -1286,6 +2512,17 @@ define i1 @auto_gen_109(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_109_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_109_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_110(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_110(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
@@ -1297,6 +2534,17 @@ define i1 @auto_gen_110(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_110_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_110_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_111(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_111(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
@@ -1308,6 +2556,17 @@ define i1 @auto_gen_111(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_111_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_111_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_112(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_112(
 ; CHECK-NEXT:    ret i1 true
@@ -1318,6 +2577,16 @@ define i1 @auto_gen_112(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_112_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_112_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_113(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_113(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
@@ -1329,6 +2598,17 @@ define i1 @auto_gen_113(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_113_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_113_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ueq double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_114(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_114(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
@@ -1340,6 +2620,17 @@ define i1 @auto_gen_114(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_114_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_114_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ugt double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp ugt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_115(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_115(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
@@ -1351,6 +2642,17 @@ define i1 @auto_gen_115(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_115_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_115_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uge double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp uge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_116(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_116(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
@@ -1362,6 +2664,17 @@ define i1 @auto_gen_116(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_116_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_116_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp ult double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_117(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_117(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
@@ -1373,6 +2686,17 @@ define i1 @auto_gen_117(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_117_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_117_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ule double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp ule double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_118(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_118(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
@@ -1384,6 +2708,17 @@ define i1 @auto_gen_118(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_118_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_118_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp une double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp une double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_119(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_119(
 ; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
@@ -1395,6 +2730,17 @@ define i1 @auto_gen_119(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_119_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_119_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = fcmp uno double [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %cmp = fcmp uno double %a, %b
+  %cmp1 = fcmp uno double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_120(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_120(
 ; CHECK-NEXT:    ret i1 true
@@ -1405,6 +2751,16 @@ define i1 @auto_gen_120(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_120_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_120_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp false double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_121(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_121(
 ; CHECK-NEXT:    ret i1 true
@@ -1415,6 +2771,16 @@ define i1 @auto_gen_121(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_121_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_121_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp oeq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_122(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_122(
 ; CHECK-NEXT:    ret i1 true
@@ -1425,6 +2791,16 @@ define i1 @auto_gen_122(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_122_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_122_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp ogt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_123(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_123(
 ; CHECK-NEXT:    ret i1 true
@@ -1435,6 +2811,16 @@ define i1 @auto_gen_123(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_123_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_123_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp oge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_124(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_124(
 ; CHECK-NEXT:    ret i1 true
@@ -1445,6 +2831,16 @@ define i1 @auto_gen_124(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_124_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_124_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp olt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_125(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_125(
 ; CHECK-NEXT:    ret i1 true
@@ -1455,6 +2851,16 @@ define i1 @auto_gen_125(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_125_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_125_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp ole double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_126(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_126(
 ; CHECK-NEXT:    ret i1 true
@@ -1465,6 +2871,16 @@ define i1 @auto_gen_126(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_126_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_126_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp one double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_127(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_127(
 ; CHECK-NEXT:    ret i1 true
@@ -1475,6 +2891,16 @@ define i1 @auto_gen_127(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_127_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_127_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp ord double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_128(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_128(
 ; CHECK-NEXT:    ret i1 true
@@ -1485,6 +2911,16 @@ define i1 @auto_gen_128(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_128_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_128_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp ueq double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_129(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_129(
 ; CHECK-NEXT:    ret i1 true
@@ -1495,6 +2931,16 @@ define i1 @auto_gen_129(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_129_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_129_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp ugt double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_130(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_130(
 ; CHECK-NEXT:    ret i1 true
@@ -1505,6 +2951,16 @@ define i1 @auto_gen_130(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_130_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_130_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp uge double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_131(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_131(
 ; CHECK-NEXT:    ret i1 true
@@ -1515,6 +2971,16 @@ define i1 @auto_gen_131(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_131_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_131_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp ult double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_132(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_132(
 ; CHECK-NEXT:    ret i1 true
@@ -1525,6 +2991,16 @@ define i1 @auto_gen_132(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_132_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_132_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp ule double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_133(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_133(
 ; CHECK-NEXT:    ret i1 true
@@ -1535,6 +3011,16 @@ define i1 @auto_gen_133(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_133_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_133_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp une double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_134(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_134(
 ; CHECK-NEXT:    ret i1 true
@@ -1545,6 +3031,16 @@ define i1 @auto_gen_134(double %a, double %b) {
   ret i1 %retval
 }
 
+define i1 @auto_gen_134_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_134_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp uno double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}
+
 define i1 @auto_gen_135(double %a, double %b) {
 ; CHECK-LABEL: @auto_gen_135(
 ; CHECK-NEXT:    ret i1 true
@@ -1554,3 +3050,13 @@ define i1 @auto_gen_135(double %a, double %b) {
   %retval = or i1 %cmp, %cmp1
   ret i1 %retval
 }
+
+define i1 @auto_gen_135_logical(double %a, double %b) {
+; CHECK-LABEL: @auto_gen_135_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %cmp = fcmp true double %a, %b
+  %cmp1 = fcmp true double %a, %b
+  %retval = select i1 %cmp, i1 true, i1 %cmp1
+  ret i1 %retval
+}

diff  --git a/llvm/test/Transforms/InstCombine/or.ll b/llvm/test/Transforms/InstCombine/or.ll
index b5da1734c102..ff6244526563 100644
--- a/llvm/test/Transforms/InstCombine/or.ll
+++ b/llvm/test/Transforms/InstCombine/or.ll
@@ -37,6 +37,18 @@ define i1 @test14(i32 %A, i32 %B) {
   ret i1 %D
 }
 
+define i1 @test14_logical(i32 %A, i32 %B) {
+; CHECK-LABEL: @test14_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %C1 = icmp ult i32 %A, %B
+  %C2 = icmp ugt i32 %A, %B
+  ; (A < B) | (A > B) === A != B
+  %D = select i1 %C1, i1 true, i1 %C2
+  ret i1 %D
+}
+
 define i1 @test15(i32 %A, i32 %B) {
 ; CHECK-LABEL: @test15(
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]
@@ -49,6 +61,18 @@ define i1 @test15(i32 %A, i32 %B) {
   ret i1 %D
 }
 
+define i1 @test15_logical(i32 %A, i32 %B) {
+; CHECK-LABEL: @test15_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %C1 = icmp ult i32 %A, %B
+  %C2 = icmp eq i32 %A, %B
+  ; (A < B) | (A == B) === A <= B
+  %D = select i1 %C1, i1 true, i1 %C2
+  ret i1 %D
+}
+
 define i32 @test16(i32 %A) {
 ; CHECK-LABEL: @test16(
 ; CHECK-NEXT:    ret i32 [[A:%.*]]
@@ -85,6 +109,18 @@ define i1 @test18(i32 %A) {
   ret i1 %D
 }
 
+define i1 @test18_logical(i32 %A) {
+; CHECK-LABEL: @test18_logical(
+; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -50
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[A_OFF]], 49
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %B = icmp sge i32 %A, 100
+  %C = icmp slt i32 %A, 50
+  %D = select i1 %B, i1 true, i1 %C
+  ret i1 %D
+}
+
 ; FIXME: Vectors should fold too.
 define <2 x i1> @test18vec(<2 x i32> %A) {
 ; CHECK-LABEL: @test18vec(
@@ -172,6 +208,20 @@ define i1 @test25(i32 %A, i32 %B) {
   ret i1 %F
 }
 
+define i1 @test25_logical(i32 %A, i32 %B) {
+; CHECK-LABEL: @test25_logical(
+; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
+; CHECK-NEXT:    [[D:%.*]] = icmp ne i32 [[B:%.*]], 57
+; CHECK-NEXT:    [[F:%.*]] = and i1 [[C]], [[D]]
+; CHECK-NEXT:    ret i1 [[F]]
+;
+  %C = icmp eq i32 %A, 0
+  %D = icmp eq i32 %B, 57
+  %E = select i1 %C, i1 true, i1 %D
+  %F = xor i1 %E, -1
+  ret i1 %F
+}
+
 ; PR5634
 define i1 @test26(i32 %A, i32 %B) {
 ; CHECK-LABEL: @test26(
@@ -186,6 +236,19 @@ define i1 @test26(i32 %A, i32 %B) {
   ret i1 %D
 }
 
+define i1 @test26_logical(i32 %A, i32 %B) {
+; CHECK-LABEL: @test26_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %C1 = icmp eq i32 %A, 0
+  %C2 = icmp eq i32 %B, 0
+  ; (A == 0) & (A == 0)   -->   (A|B) == 0
+  %D = select i1 %C1, i1 %C2, i1 false
+  ret i1 %D
+}
+
 define i1 @test27(i32* %A, i32* %B) {
 ; CHECK-LABEL: @test27(
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32* [[A:%.*]], null
@@ -228,6 +291,19 @@ define i1 @test28(i32 %A, i32 %B) {
   ret i1 %D
 }
 
+define i1 @test28_logical(i32 %A, i32 %B) {
+; CHECK-LABEL: @test28_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %C1 = icmp ne i32 %A, 0
+  %C2 = icmp ne i32 %B, 0
+  ; (A != 0) | (A != 0)   -->   (A|B) != 0
+  %D = select i1 %C1, i1 true, i1 %C2
+  ret i1 %D
+}
+
 define i1 @test29(i32* %A, i32* %B) {
 ; CHECK-LABEL: @test29(
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32* [[A:%.*]], null
@@ -342,6 +418,16 @@ define i1 @test33(i1 %X, i1 %Y) {
   ret i1 %b
 }
 
+define i1 @test33_logical(i1 %X, i1 %Y) {
+; CHECK-LABEL: @test33_logical(
+; CHECK-NEXT:    [[A:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[A]]
+;
+  %a = select i1 %X, i1 true, i1 %Y
+  %b = select i1 %a, i1 true, i1 %X
+  ret i1 %b
+}
+
 define i32 @test34(i32 %X, i32 %Y) {
 ; CHECK-LABEL: @test34(
 ; CHECK-NEXT:    [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
@@ -377,6 +463,20 @@ define i1 @test36(i32 %x) {
   ret i1 %ret2
 }
 
+define i1 @test36_logical(i32 %x) {
+; CHECK-LABEL: @test36_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -23
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp1 = icmp eq i32 %x, 23
+  %cmp2 = icmp eq i32 %x, 24
+  %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
+  %cmp3 = icmp eq i32 %x, 25
+  %ret2 = select i1 %ret1, i1 true, i1 %cmp3
+  ret i1 %ret2
+}
+
 define i1 @test37(i32 %x) {
 ; CHECK-LABEL: @test37(
 ; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[X:%.*]], 7
@@ -390,6 +490,19 @@ define i1 @test37(i32 %x) {
   ret i1 %ret1
 }
 
+define i1 @test37_logical(i32 %x) {
+; CHECK-LABEL: @test37_logical(
+; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[X:%.*]], 7
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[ADD1]], 31
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %add1 = add i32 %x, 7
+  %cmp1 = icmp ult i32 %add1, 30
+  %cmp2 = icmp eq i32 %x, 23
+  %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
+  ret i1 %ret1
+}
+
 define <2 x i1> @test37_uniform(<2 x i32> %x) {
 ; CHECK-LABEL: @test37_uniform(
 ; CHECK-NEXT:    [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 7>
@@ -435,6 +548,21 @@ define i1 @test38(i32 %x) {
   ret i1 %ret1
 }
 
+define i1 @test38_logical(i32 %x) {
+; CHECK-LABEL: @test38_logical(
+; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[X:%.*]], 7
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[X]], 23
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[ADD1]], 30
+; CHECK-NEXT:    [[RET1:%.*]] = or i1 [[CMP1]], [[CMP2]]
+; CHECK-NEXT:    ret i1 [[RET1]]
+;
+  %add1 = add i32 %x, 7
+  %cmp1 = icmp eq i32 %x, 23
+  %cmp2 = icmp ult i32 %add1, 30
+  %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
+  ret i1 %ret1
+}
+
 define <2 x i1> @test38_nonuniform(<2 x i32> %x) {
 ; CHECK-LABEL: @test38_nonuniform(
 ; CHECK-NEXT:    [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 24>
@@ -649,6 +777,21 @@ define i1 @test46(i8 signext %c)  {
   ret i1 %or
 }
 
+define i1 @test46_logical(i8 signext %c)  {
+; CHECK-LABEL: @test46_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[C:%.*]], -33
+; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], -65
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 26
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %c.off = add i8 %c, -97
+  %cmp1 = icmp ult i8 %c.off, 26
+  %c.off17 = add i8 %c, -65
+  %cmp2 = icmp ult i8 %c.off17, 26
+  %or = select i1 %cmp1, i1 true, i1 %cmp2
+  ret i1 %or
+}
+
 define <2 x i1> @test46_uniform(<2 x i8> %c)  {
 ; CHECK-LABEL: @test46_uniform(
 ; CHECK-NEXT:    [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -97, i8 -97>
@@ -698,6 +841,21 @@ define i1 @test47(i8 signext %c)  {
   ret i1 %or
 }
 
+define i1 @test47_logical(i8 signext %c)  {
+; CHECK-LABEL: @test47_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[C:%.*]], -33
+; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], -65
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 27
+; CHECK-NEXT:    ret i1 [[TMP3]]
+;
+  %c.off = add i8 %c, -65
+  %cmp1 = icmp ule i8 %c.off, 26
+  %c.off17 = add i8 %c, -97
+  %cmp2 = icmp ule i8 %c.off17, 26
+  %or = select i1 %cmp1, i1 true, i1 %cmp2
+  ret i1 %or
+}
+
 define <2 x i1> @test47_nonuniform(<2 x i8> %c)  {
 ; CHECK-LABEL: @test47_nonuniform(
 ; CHECK-NEXT:    [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -65, i8 -97>
@@ -829,6 +987,21 @@ define i1 @or_andn_cmp_1(i32 %a, i32 %b, i32 %c) {
   ret i1 %or
 }
 
+define i1 @or_andn_cmp_1_logical(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: @or_andn_cmp_1_logical(
+; CHECK-NEXT:    [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X]], [[Y]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %x = icmp sgt i32 %a, %b
+  %x_inv = icmp sle i32 %a, %b
+  %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
+  %and = select i1 %y, i1 %x_inv, i1 false
+  %or = select i1 %x, i1 true, i1 %and
+  ret i1 %or
+}
+
 ; Commute the 'or':
 ; ((Y & ~X) | X) -> (X | Y), where 'not' is an inverted cmp
 
@@ -865,6 +1038,21 @@ define i1 @or_andn_cmp_3(i72 %a, i72 %b, i72 %c) {
   ret i1 %or
 }
 
+define i1 @or_andn_cmp_3_logical(i72 %a, i72 %b, i72 %c) {
+; CHECK-LABEL: @or_andn_cmp_3_logical(
+; CHECK-NEXT:    [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X]], [[Y]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %x = icmp ugt i72 %a, %b
+  %x_inv = icmp ule i72 %a, %b
+  %y = icmp ugt i72 %c, 42      ; thwart complexity-based ordering
+  %and = select i1 %x_inv, i1 %y, i1 false
+  %or = select i1 %x, i1 true, i1 %and
+  ret i1 %or
+}
+
 ; Commute the 'or':
 ; ((~X & Y) | X) -> (X | Y), where 'not' is an inverted cmp
 
@@ -901,6 +1089,21 @@ define i1 @orn_and_cmp_1(i37 %a, i37 %b, i37 %c) {
   ret i1 %or
 }
 
+define i1 @orn_and_cmp_1_logical(i37 %a, i37 %b, i37 %c) {
+; CHECK-LABEL: @orn_and_cmp_1_logical(
+; CHECK-NEXT:    [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X_INV]], [[Y]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %x = icmp sgt i37 %a, %b
+  %x_inv = icmp sle i37 %a, %b
+  %y = icmp ugt i37 %c, 42      ; thwart complexity-based ordering
+  %and = select i1 %y, i1 %x, i1 false
+  %or = select i1 %x_inv, i1 true, i1 %and
+  ret i1 %or
+}
+
 ; Commute the 'or':
 ; ((Y & X) | ~X) -> (~X | Y), where 'not' is an inverted cmp
 
@@ -919,6 +1122,21 @@ define i1 @orn_and_cmp_2(i16 %a, i16 %b, i16 %c) {
   ret i1 %or
 }
 
+define i1 @orn_and_cmp_2_logical(i16 %a, i16 %b, i16 %c) {
+; CHECK-LABEL: @orn_and_cmp_2_logical(
+; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %x = icmp sge i16 %a, %b
+  %x_inv = icmp slt i16 %a, %b
+  %y = icmp ugt i16 %c, 42      ; thwart complexity-based ordering
+  %and = select i1 %y, i1 %x, i1 false
+  %or = select i1 %and, i1 true, i1 %x_inv
+  ret i1 %or
+}
+
 ; Commute the 'and':
 ; (~X | (X & Y)) -> (~X | Y), where 'not' is an inverted cmp
 
@@ -955,6 +1173,21 @@ define i1 @orn_and_cmp_4(i32 %a, i32 %b, i32 %c) {
   ret i1 %or
 }
 
+define i1 @orn_and_cmp_4_logical(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: @orn_and_cmp_4_logical(
+; CHECK-NEXT:    [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
+; CHECK-NEXT:    ret i1 [[OR]]
+;
+  %x = icmp eq i32 %a, %b
+  %x_inv = icmp ne i32 %a, %b
+  %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
+  %and = select i1 %x, i1 %y, i1 false
+  %or = select i1 %and, i1 true, i1 %x_inv
+  ret i1 %or
+}
+
 ; The constant vectors are inverses. Make sure we can turn this into a select without crashing trying to truncate the constant to 16xi1.
 define <16 x i1> @test51(<16 x i1> %arg, <16 x i1> %arg1) {
 ; CHECK-LABEL: @test51(
@@ -1002,6 +1235,38 @@ end:
   ret i32 %conv8
 }
 
+define i32 @PR46712_logical(i1 %x, i1 %y, i1 %b, i64 %z) {
+; CHECK-LABEL: @PR46712_logical(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
+; CHECK:       true:
+; CHECK-NEXT:    [[BOOL5_NOT:%.*]] = icmp eq i64 [[Z:%.*]], 0
+; CHECK-NEXT:    [[SEL:%.*]] = zext i1 [[BOOL5_NOT]] to i32
+; CHECK-NEXT:    br label [[END]]
+; CHECK:       end:
+; CHECK-NEXT:    [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SEL]], [[TRUE]] ]
+; CHECK-NEXT:    ret i32 [[T5]]
+;
+entry:
+  %t2 = select i1 %x, i1 true, i1 %y
+  %conv = sext i1 %t2 to i32
+  %cmp = icmp sge i32 %conv, 1
+  %conv2 = zext i1 %cmp to i64
+  br i1 %b, label %true, label %end
+
+true:
+  %bool4 = icmp eq i64 %conv2, 0
+  %bool5 = icmp ne i64 %z, 0
+  %and = select i1 %bool4, i1 %bool5, i1 false
+  %sel = select i1 %and, i1 false, i1 true
+  br label %end
+
+end:
+  %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
+  %conv8 = zext i1 %t5 to i32
+  ret i32 %conv8
+}
+
 define i32 @test1(i32 %x, i32 %y) {
 ; CHECK-LABEL: @test1(
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]

diff  --git a/llvm/test/Transforms/InstCombine/prevent-cmp-merge.ll b/llvm/test/Transforms/InstCombine/prevent-cmp-merge.ll
index ab37c7d56232..17d1dd28e126 100644
--- a/llvm/test/Transforms/InstCombine/prevent-cmp-merge.ll
+++ b/llvm/test/Transforms/InstCombine/prevent-cmp-merge.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -instcombine -S | FileCheck %s
 ;
 ; This test makes sure that InstCombine does not replace the sequence of
@@ -6,8 +7,12 @@
 
 define zeroext i1 @test1(i32 %lhs, i32 %rhs) {
 ; CHECK-LABEL: @test1(
-; CHECK-NEXT: %xor = xor i32 %lhs, 5
-; CHECK-NEXT: %cmp1 = icmp eq i32 %xor, 10
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[LHS:%.*]], 5
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[XOR]], 10
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[XOR]], [[RHS:%.*]]
+; CHECK-NEXT:    [[SEL:%.*]] = or i1 [[CMP1]], [[CMP2]]
+; CHECK-NEXT:    ret i1 [[SEL]]
+;
 
   %xor = xor i32 %lhs, 5
   %cmp1 = icmp eq i32 %xor, 10
@@ -16,10 +21,30 @@ define zeroext i1 @test1(i32 %lhs, i32 %rhs) {
   ret i1 %sel
 }
 
+define zeroext i1 @test1_logical(i32 %lhs, i32 %rhs) {
+; CHECK-LABEL: @test1_logical(
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[LHS:%.*]], 5
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[XOR]], 10
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[XOR]], [[RHS:%.*]]
+; CHECK-NEXT:    [[SEL:%.*]] = or i1 [[CMP1]], [[CMP2]]
+; CHECK-NEXT:    ret i1 [[SEL]]
+;
+
+  %xor = xor i32 %lhs, 5
+  %cmp1 = icmp eq i32 %xor, 10
+  %cmp2 = icmp eq i32 %xor, %rhs
+  %sel = select i1 %cmp1, i1 true, i1 %cmp2
+  ret i1 %sel
+}
+
 define zeroext i1 @test2(i32 %lhs, i32 %rhs) {
 ; CHECK-LABEL: @test2(
-; CHECK-NEXT: %xor = xor i32 %lhs, %rhs
-; CHECK-NEXT: %cmp1 = icmp eq i32 %xor, 0
+; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[LHS:%.*]], [[RHS:%.*]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[XOR]], 0
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[XOR]], 32
+; CHECK-NEXT:    [[SEL:%.*]] = xor i1 [[CMP1]], [[CMP2]]
+; CHECK-NEXT:    ret i1 [[SEL]]
+;
 
   %xor = xor i32 %lhs, %rhs
   %cmp1 = icmp eq i32 %xor, 0
@@ -30,8 +55,12 @@ define zeroext i1 @test2(i32 %lhs, i32 %rhs) {
 
 define zeroext i1 @test3(i32 %lhs, i32 %rhs) {
 ; CHECK-LABEL: @test3(
-; CHECK-NEXT: %sub = sub nsw i32 %lhs, %rhs
-; CHECK-NEXT: %cmp1 = icmp eq i32 %sub, 0
+; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[LHS:%.*]], [[RHS:%.*]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[SUB]], 0
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[SUB]], 31
+; CHECK-NEXT:    [[SEL:%.*]] = or i1 [[CMP1]], [[CMP2]]
+; CHECK-NEXT:    ret i1 [[SEL]]
+;
 
   %sub = sub nsw i32 %lhs, %rhs
   %cmp1 = icmp eq i32 %sub, 0
@@ -39,3 +68,19 @@ define zeroext i1 @test3(i32 %lhs, i32 %rhs) {
   %sel = or i1 %cmp1, %cmp2
   ret i1 %sel
 }
+
+define zeroext i1 @test3_logical(i32 %lhs, i32 %rhs) {
+; CHECK-LABEL: @test3_logical(
+; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[LHS:%.*]], [[RHS:%.*]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[SUB]], 0
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[SUB]], 31
+; CHECK-NEXT:    [[SEL:%.*]] = or i1 [[CMP1]], [[CMP2]]
+; CHECK-NEXT:    ret i1 [[SEL]]
+;
+
+  %sub = sub nsw i32 %lhs, %rhs
+  %cmp1 = icmp eq i32 %sub, 0
+  %cmp2 = icmp eq i32 %sub, 31
+  %sel = select i1 %cmp1, i1 true, i1 %cmp2
+  ret i1 %sel
+}

diff  --git a/llvm/test/Transforms/InstCombine/range-check.ll b/llvm/test/Transforms/InstCombine/range-check.ll
index ba77beae0f68..5d56e0a90360 100644
--- a/llvm/test/Transforms/InstCombine/range-check.ll
+++ b/llvm/test/Transforms/InstCombine/range-check.ll
@@ -17,6 +17,19 @@ define i1 @test_and1(i32 %x, i32 %n) {
   ret i1 %c
 }
 
+define i1 @test_and1_logical(i32 %x, i32 %n) {
+; CHECK-LABEL: @test_and1_logical(
+; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[NN]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %nn = and i32 %n, 2147483647
+  %a = icmp sge i32 %x, 0
+  %b = icmp slt i32 %x, %nn
+  %c = select i1 %a, i1 %b, i1 false
+  ret i1 %c
+}
+
 define i1 @test_and2(i32 %x, i32 %n) {
 ; CHECK-LABEL: @test_and2(
 ; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -30,6 +43,19 @@ define i1 @test_and2(i32 %x, i32 %n) {
   ret i1 %c
 }
 
+define i1 @test_and2_logical(i32 %x, i32 %n) {
+; CHECK-LABEL: @test_and2_logical(
+; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp uge i32 [[NN]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %nn = and i32 %n, 2147483647
+  %a = icmp sgt i32 %x, -1
+  %b = icmp sle i32 %x, %nn
+  %c = select i1 %a, i1 %b, i1 false
+  ret i1 %c
+}
+
 define i1 @test_and3(i32 %x, i32 %n) {
 ; CHECK-LABEL: @test_and3(
 ; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -43,6 +69,19 @@ define i1 @test_and3(i32 %x, i32 %n) {
   ret i1 %c
 }
 
+define i1 @test_and3_logical(i32 %x, i32 %n) {
+; CHECK-LABEL: @test_and3_logical(
+; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[NN]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %nn = and i32 %n, 2147483647
+  %a = icmp sgt i32 %nn, %x
+  %b = icmp sge i32 %x, 0
+  %c = select i1 %a, i1 %b, i1 false
+  ret i1 %c
+}
+
 define i1 @test_and4(i32 %x, i32 %n) {
 ; CHECK-LABEL: @test_and4(
 ; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -56,6 +95,19 @@ define i1 @test_and4(i32 %x, i32 %n) {
   ret i1 %c
 }
 
+define i1 @test_and4_logical(i32 %x, i32 %n) {
+; CHECK-LABEL: @test_and4_logical(
+; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp uge i32 [[NN]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %nn = and i32 %n, 2147483647
+  %a = icmp sge i32 %nn, %x
+  %b = icmp sge i32 %x, 0
+  %c = select i1 %a, i1 %b, i1 false
+  ret i1 %c
+}
+
 define i1 @test_or1(i32 %x, i32 %n) {
 ; CHECK-LABEL: @test_or1(
 ; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -69,6 +121,19 @@ define i1 @test_or1(i32 %x, i32 %n) {
   ret i1 %c
 }
 
+define i1 @test_or1_logical(i32 %x, i32 %n) {
+; CHECK-LABEL: @test_or1_logical(
+; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[NN]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %nn = and i32 %n, 2147483647
+  %a = icmp slt i32 %x, 0
+  %b = icmp sge i32 %x, %nn
+  %c = select i1 %a, i1 true, i1 %b
+  ret i1 %c
+}
+
 define i1 @test_or2(i32 %x, i32 %n) {
 ; CHECK-LABEL: @test_or2(
 ; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -82,6 +147,19 @@ define i1 @test_or2(i32 %x, i32 %n) {
   ret i1 %c
 }
 
+define i1 @test_or2_logical(i32 %x, i32 %n) {
+; CHECK-LABEL: @test_or2_logical(
+; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[NN]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %nn = and i32 %n, 2147483647
+  %a = icmp sle i32 %x, -1
+  %b = icmp sgt i32 %x, %nn
+  %c = select i1 %a, i1 true, i1 %b
+  ret i1 %c
+}
+
 define i1 @test_or3(i32 %x, i32 %n) {
 ; CHECK-LABEL: @test_or3(
 ; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -95,6 +173,19 @@ define i1 @test_or3(i32 %x, i32 %n) {
   ret i1 %c
 }
 
+define i1 @test_or3_logical(i32 %x, i32 %n) {
+; CHECK-LABEL: @test_or3_logical(
+; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[NN]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %nn = and i32 %n, 2147483647
+  %a = icmp sle i32 %nn, %x
+  %b = icmp slt i32 %x, 0
+  %c = select i1 %a, i1 true, i1 %b
+  ret i1 %c
+}
+
 define i1 @test_or4(i32 %x, i32 %n) {
 ; CHECK-LABEL: @test_or4(
 ; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -108,6 +199,19 @@ define i1 @test_or4(i32 %x, i32 %n) {
   ret i1 %c
 }
 
+define i1 @test_or4_logical(i32 %x, i32 %n) {
+; CHECK-LABEL: @test_or4_logical(
+; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[NN]], [[X:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %nn = and i32 %n, 2147483647
+  %a = icmp slt i32 %nn, %x
+  %b = icmp slt i32 %x, 0
+  %c = select i1 %a, i1 true, i1 %b
+  ret i1 %c
+}
+
 ; Negative tests
 
 define i1 @negative1(i32 %x, i32 %n) {
@@ -125,6 +229,21 @@ define i1 @negative1(i32 %x, i32 %n) {
   ret i1 %c
 }
 
+define i1 @negative1_logical(i32 %x, i32 %n) {
+; CHECK-LABEL: @negative1_logical(
+; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[NN]], [[X:%.*]]
+; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[X]], 0
+; CHECK-NEXT:    [[C:%.*]] = and i1 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %nn = and i32 %n, 2147483647
+  %a = icmp slt i32 %x, %nn
+  %b = icmp sgt i32 %x, 0      ; should be: icmp sge
+  %c = select i1 %a, i1 %b, i1 false
+  ret i1 %c
+}
+
 define i1 @negative2(i32 %x, i32 %n) {
 ; CHECK-LABEL: @negative2(
 ; CHECK-NEXT:    [[A:%.*]] = icmp slt i32 [[X:%.*]], [[N:%.*]]
@@ -138,6 +257,19 @@ define i1 @negative2(i32 %x, i32 %n) {
   ret i1 %c
 }
 
+define i1 @negative2_logical(i32 %x, i32 %n) {
+; CHECK-LABEL: @negative2_logical(
+; CHECK-NEXT:    [[A:%.*]] = icmp slt i32 [[X:%.*]], [[N:%.*]]
+; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[X]], -1
+; CHECK-NEXT:    [[C:%.*]] = and i1 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %a = icmp slt i32 %x, %n     ; n can be negative
+  %b = icmp sge i32 %x, 0
+  %c = select i1 %a, i1 %b, i1 false
+  ret i1 %c
+}
+
 define i1 @negative3(i32 %x, i32 %y, i32 %n) {
 ; CHECK-LABEL: @negative3(
 ; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -153,6 +285,21 @@ define i1 @negative3(i32 %x, i32 %y, i32 %n) {
   ret i1 %c
 }
 
+define i1 @negative3_logical(i32 %x, i32 %y, i32 %n) {
+; CHECK-LABEL: @negative3_logical(
+; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[NN]], [[X:%.*]]
+; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[Y:%.*]], -1
+; CHECK-NEXT:    [[C:%.*]] = and i1 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %nn = and i32 %n, 2147483647
+  %a = icmp slt i32 %x, %nn
+  %b = icmp sge i32 %y, 0      ; should compare %x and not %y
+  %c = select i1 %a, i1 %b, i1 false
+  ret i1 %c
+}
+
 define i1 @negative4(i32 %x, i32 %n) {
 ; CHECK-LABEL: @negative4(
 ; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -168,6 +315,21 @@ define i1 @negative4(i32 %x, i32 %n) {
   ret i1 %c
 }
 
+define i1 @negative4_logical(i32 %x, i32 %n) {
+; CHECK-LABEL: @negative4_logical(
+; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
+; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[NN]], [[X:%.*]]
+; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[X]], -1
+; CHECK-NEXT:    [[C:%.*]] = and i1 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %nn = and i32 %n, 2147483647
+  %a = icmp ne i32 %x, %nn     ; should be: icmp slt/sle
+  %b = icmp sge i32 %x, 0
+  %c = select i1 %a, i1 %b, i1 false
+  ret i1 %c
+}
+
 define i1 @negative5(i32 %x, i32 %n) {
 ; CHECK-LABEL: @negative5(
 ; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
@@ -183,3 +345,18 @@ define i1 @negative5(i32 %x, i32 %n) {
   ret i1 %c
 }
 
+define i1 @negative5_logical(i32 %x, i32 %n) {
+; CHECK-LABEL: @negative5_logical(
+; CHECK-NEXT:    [[NN:%.*]] = and i32 [[N:%.*]], 2147483647
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[NN]], [[X:%.*]]
+; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[X]], -1
+; CHECK-NEXT:    [[C:%.*]] = or i1 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %nn = and i32 %n, 2147483647
+  %a = icmp slt i32 %x, %nn
+  %b = icmp sge i32 %x, 0
+  %c = select i1 %a, i1 true, i1 %b            ; should be: and
+  ret i1 %c
+}
+

diff  --git a/llvm/test/Transforms/InstCombine/result-of-add-of-negative-is-non-zero-and-no-underflow.ll b/llvm/test/Transforms/InstCombine/result-of-add-of-negative-is-non-zero-and-no-underflow.ll
index 2b4686004abc..bcc62dc983c6 100644
--- a/llvm/test/Transforms/InstCombine/result-of-add-of-negative-is-non-zero-and-no-underflow.ll
+++ b/llvm/test/Transforms/InstCombine/result-of-add-of-negative-is-non-zero-and-no-underflow.ll
@@ -24,6 +24,23 @@ define i1 @t0_bad(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t0_bad_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t0_bad_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ult i8 [[ADJUSTED]], [[BASE]]
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  %no_underflow = icmp ult i8 %adjusted, %base
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
+
 ; Ok, base is non-zero.
 define i1 @t1(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t1(
@@ -46,6 +63,27 @@ define i1 @t1(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t1_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t1_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[BASE:%.*]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[BASE]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp = icmp slt i8 %base, 0
+  call void @llvm.assume(i1 %cmp)
+
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  %no_underflow = icmp ult i8 %adjusted, %base
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
+
 ; Ok, offset is non-zero.
 define i1 @t2(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t2(
@@ -68,6 +106,27 @@ define i1 @t2(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t2_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t2_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[OFFSET:%.*]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp = icmp slt i8 %offset, 0
+  call void @llvm.assume(i1 %cmp)
+
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  %no_underflow = icmp ult i8 %adjusted, %base
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
+
 ; We need to produce extra instruction, so one of icmp's must go away.
 define i1 @t3_oneuse0(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t3_oneuse0(
@@ -92,6 +151,30 @@ define i1 @t3_oneuse0(i8 %base, i8 %offset) {
   %r = and i1 %not_null, %no_underflow
   ret i1 %r
 }
+
+define i1 @t3_oneuse0_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t3_oneuse0_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[BASE:%.*]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[BASE]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp = icmp slt i8 %base, 0
+  call void @llvm.assume(i1 %cmp)
+
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  call void @use1(i1 %not_null)
+  %no_underflow = icmp ult i8 %adjusted, %base
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
 define i1 @t4_oneuse1(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t4_oneuse1(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[BASE:%.*]], 0
@@ -115,6 +198,30 @@ define i1 @t4_oneuse1(i8 %base, i8 %offset) {
   %r = and i1 %not_null, %no_underflow
   ret i1 %r
 }
+
+define i1 @t4_oneuse1_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t4_oneuse1_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[BASE:%.*]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ult i8 [[ADJUSTED]], [[BASE]]
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[BASE]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp = icmp slt i8 %base, 0
+  call void @llvm.assume(i1 %cmp)
+
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  %no_underflow = icmp ult i8 %adjusted, %base
+  call void @use1(i1 %no_underflow)
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
 define i1 @t5_oneuse2_bad(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t5_oneuse2_bad(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[BASE:%.*]], 0
@@ -141,6 +248,32 @@ define i1 @t5_oneuse2_bad(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t5_oneuse2_bad_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t5_oneuse2_bad_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[BASE:%.*]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ult i8 [[ADJUSTED]], [[BASE]]
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %cmp = icmp slt i8 %base, 0
+  call void @llvm.assume(i1 %cmp)
+
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  call void @use1(i1 %not_null)
+  %no_underflow = icmp ult i8 %adjusted, %base
+  call void @use1(i1 %no_underflow)
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
+
 define i1 @t6_commutativity0(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t6_commutativity0(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[BASE:%.*]], 0
@@ -161,6 +294,27 @@ define i1 @t6_commutativity0(i8 %base, i8 %offset) {
   %r = and i1 %no_underflow, %not_null ; swapped
   ret i1 %r
 }
+
+define i1 @t6_commutativity0_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t6_commutativity0_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[BASE:%.*]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[BASE]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp = icmp slt i8 %base, 0
+  call void @llvm.assume(i1 %cmp)
+
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  %no_underflow = icmp ult i8 %adjusted, %base
+  %r = select i1 %no_underflow, i1 %not_null, i1 false ; swapped
+  ret i1 %r
+}
 define i1 @t7_commutativity1(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t7_commutativity1(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[BASE:%.*]], 0
@@ -181,6 +335,27 @@ define i1 @t7_commutativity1(i8 %base, i8 %offset) {
   %r = and i1 %not_null, %no_underflow
   ret i1 %r
 }
+
+define i1 @t7_commutativity1_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t7_commutativity1_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[BASE:%.*]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[BASE]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp = icmp slt i8 %base, 0
+  call void @llvm.assume(i1 %cmp)
+
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  %no_underflow = icmp ugt i8 %base, %adjusted ; swapped
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
 define i1 @t7_commutativity3(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t7_commutativity3(
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[BASE:%.*]], 0
@@ -202,6 +377,27 @@ define i1 @t7_commutativity3(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t7_commutativity3_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t7_commutativity3_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[BASE:%.*]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[BASE]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp = icmp slt i8 %base, 0
+  call void @llvm.assume(i1 %cmp)
+
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  %no_underflow = icmp ugt i8 %base, %adjusted ; swapped
+  %r = select i1 %no_underflow, i1 %not_null, i1 false ; swapped
+  ret i1 %r
+}
+
 ; We could have the opposite question, did we get null or overflow happened?
 define i1 @t8(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t8(
@@ -224,6 +420,27 @@ define i1 @t8(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t8_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t8_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[BASE:%.*]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[BASE]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i8 [[TMP1]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp = icmp slt i8 %base, 0
+  call void @llvm.assume(i1 %cmp)
+
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp eq i8 %adjusted, 0
+  %no_underflow = icmp uge i8 %adjusted, %base
+  %r = select i1 %not_null, i1 true, i1 %no_underflow
+  ret i1 %r
+}
+
 ; The comparison can be with any of the values being added.
 define i1 @t9(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t9(
@@ -245,3 +462,24 @@ define i1 @t9(i8 %base, i8 %offset) {
   %r = and i1 %not_null, %no_underflow
   ret i1 %r
 }
+
+define i1 @t9_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t9_logical(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[BASE:%.*]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[BASE]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %cmp = icmp slt i8 %base, 0
+  call void @llvm.assume(i1 %cmp)
+
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  %no_underflow = icmp ult i8 %adjusted, %offset
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}

diff  --git a/llvm/test/Transforms/InstCombine/result-of-add-of-negative-or-zero-is-non-zero-and-no-underflow.ll b/llvm/test/Transforms/InstCombine/result-of-add-of-negative-or-zero-is-non-zero-and-no-underflow.ll
index 7b29bcdd2531..e2f256140b51 100644
--- a/llvm/test/Transforms/InstCombine/result-of-add-of-negative-or-zero-is-non-zero-and-no-underflow.ll
+++ b/llvm/test/Transforms/InstCombine/result-of-add-of-negative-or-zero-is-non-zero-and-no-underflow.ll
@@ -22,6 +22,22 @@ define i1 @t0(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t0_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t0_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  %no_underflow = icmp ule i8 %adjusted, %base
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
+
 ; We need to produce extra instruction, so one of icmp's must go away.
 define i1 @t1_oneuse0(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t1_oneuse0(
@@ -41,6 +57,25 @@ define i1 @t1_oneuse0(i8 %base, i8 %offset) {
   %r = and i1 %not_null, %no_underflow
   ret i1 %r
 }
+
+define i1 @t1_oneuse0_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t1_oneuse0_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  call void @use1(i1 %not_null)
+  %no_underflow = icmp ule i8 %adjusted, %base
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
 define i1 @t2_oneuse1(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t2_oneuse1(
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
@@ -59,6 +94,25 @@ define i1 @t2_oneuse1(i8 %base, i8 %offset) {
   %r = and i1 %not_null, %no_underflow
   ret i1 %r
 }
+
+define i1 @t2_oneuse1_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t2_oneuse1_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ule i8 [[ADJUSTED]], [[BASE]]
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  %no_underflow = icmp ule i8 %adjusted, %base
+  call void @use1(i1 %no_underflow)
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
 define i1 @n3_oneuse2_bad(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @n3_oneuse2_bad(
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
@@ -80,6 +134,27 @@ define i1 @n3_oneuse2_bad(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @n3_oneuse2_bad_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @n3_oneuse2_bad_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ule i8 [[ADJUSTED]], [[BASE]]
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  call void @use1(i1 %not_null)
+  %no_underflow = icmp ule i8 %adjusted, %base
+  call void @use1(i1 %no_underflow)
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
+
 define i1 @t4_commutativity0(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t4_commutativity0(
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
@@ -95,6 +170,22 @@ define i1 @t4_commutativity0(i8 %base, i8 %offset) {
   %r = and i1 %no_underflow, %not_null ; swapped
   ret i1 %r
 }
+
+define i1 @t4_commutativity0_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t4_commutativity0_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  %no_underflow = icmp ule i8 %adjusted, %base
+  %r = select i1 %no_underflow, i1 %not_null, i1 false ; swapped
+  ret i1 %r
+}
 define i1 @t5_commutativity1(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t5_commutativity1(
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
@@ -110,6 +201,22 @@ define i1 @t5_commutativity1(i8 %base, i8 %offset) {
   %r = and i1 %not_null, %no_underflow
   ret i1 %r
 }
+
+define i1 @t5_commutativity1_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t5_commutativity1_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  %no_underflow = icmp uge i8 %base, %adjusted ; swapped
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
 define i1 @t6_commutativity3(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t6_commutativity3(
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
@@ -126,6 +233,22 @@ define i1 @t6_commutativity3(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t6_commutativity3_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t6_commutativity3_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[OFFSET]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[BASE]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  %no_underflow = icmp uge i8 %base, %adjusted ; swapped
+  %r = select i1 %no_underflow, i1 %not_null, i1 false ; swapped
+  ret i1 %r
+}
+
 ; We could have the opposite question, did we get null or overflow happened?
 define i1 @t7(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t7(
@@ -143,6 +266,22 @@ define i1 @t7(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t7_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t7_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[ADJUSTED]], -1
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i8 [[TMP1]], [[BASE]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp eq i8 %adjusted, 0
+  %no_underflow = icmp ugt i8 %adjusted, %base
+  %r = select i1 %not_null, i1 true, i1 %no_underflow
+  ret i1 %r
+}
+
 ; The comparison can be with any of the values being added.
 define i1 @t8(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t8(
@@ -159,3 +298,19 @@ define i1 @t8(i8 %base, i8 %offset) {
   %r = and i1 %not_null, %no_underflow
   ret i1 %r
 }
+
+define i1 @t8_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t8_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = add i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 0, [[BASE]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %adjusted = add i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  %no_underflow = icmp ule i8 %adjusted, %offset
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}

diff  --git a/llvm/test/Transforms/InstCombine/result-of-usub-is-non-zero-and-no-overflow.ll b/llvm/test/Transforms/InstCombine/result-of-usub-is-non-zero-and-no-overflow.ll
index ae70b9259f0b..b875396a8c6d 100644
--- a/llvm/test/Transforms/InstCombine/result-of-usub-is-non-zero-and-no-overflow.ll
+++ b/llvm/test/Transforms/InstCombine/result-of-usub-is-non-zero-and-no-overflow.ll
@@ -37,6 +37,27 @@ define i1 @t0_noncanonical_ignoreme(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t0_noncanonical_ignoreme_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t0_noncanonical_ignoreme_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %adjusted = sub i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %no_underflow = icmp ule i8 %adjusted, %base
+  call void @use1(i1 %no_underflow)
+  %not_null = icmp ne i8 %adjusted, 0
+  call void @use1(i1 %not_null)
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
+
 define i1 @t1(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t1(
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
@@ -57,6 +78,27 @@ define i1 @t1(i8 %base, i8 %offset) {
   %r = and i1 %not_null, %no_underflow
   ret i1 %r
 }
+
+define i1 @t1_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t1_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %adjusted = sub i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %no_underflow = icmp uge i8 %base, %offset
+  call void @use1(i1 %no_underflow)
+  %not_null = icmp ne i8 %adjusted, 0
+  call void @use1(i1 %not_null)
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
 define i1 @t1_strict(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t1_strict(
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
@@ -77,6 +119,26 @@ define i1 @t1_strict(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t1_strict_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t1_strict_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
+; CHECK-NEXT:    ret i1 [[NO_UNDERFLOW]]
+;
+  %adjusted = sub i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %no_underflow = icmp ugt i8 %base, %offset ; same is valid for strict predicate
+  call void @use1(i1 %no_underflow)
+  %not_null = icmp ne i8 %adjusted, 0
+  call void @use1(i1 %not_null)
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
+
 define i1 @t2(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t2(
 ; CHECK-NEXT:    [[AGG:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[BASE:%.*]], i8 [[OFFSET:%.*]])
@@ -104,6 +166,33 @@ define i1 @t2(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t2_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t2_logical(
+; CHECK-NEXT:    [[AGG:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[BASE:%.*]], i8 [[OFFSET:%.*]])
+; CHECK-NEXT:    call void @useagg({ i8, i1 } [[AGG]])
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = extractvalue { i8, i1 } [[AGG]], 0
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[UNDERFLOW:%.*]] = extractvalue { i8, i1 } [[AGG]], 1
+; CHECK-NEXT:    call void @use1(i1 [[UNDERFLOW]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = xor i1 [[UNDERFLOW]], true
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %agg = call {i8, i1} @llvm.usub.with.overflow(i8 %base, i8 %offset)
+  call void @useagg({i8, i1} %agg)
+  %adjusted = extractvalue {i8, i1} %agg, 0
+  call void @use8(i8 %adjusted)
+  %underflow = extractvalue {i8, i1} %agg, 1
+  call void @use1(i1 %underflow)
+  %no_underflow = xor i1 %underflow, -1
+  call void @use1(i1 %no_underflow)
+  %not_null = icmp ne i8 %adjusted, 0
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
+
 ; Commutativity
 
 define i1 @t3_commutability0(i8 %base, i8 %offset) {
@@ -126,6 +215,27 @@ define i1 @t3_commutability0(i8 %base, i8 %offset) {
   %r = and i1 %not_null, %no_underflow
   ret i1 %r
 }
+
+define i1 @t3_commutability0_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t3_commutability0_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %adjusted = sub i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %no_underflow = icmp ule i8 %offset, %base ; swapped
+  call void @use1(i1 %no_underflow)
+  %not_null = icmp ne i8 %adjusted, 0
+  call void @use1(i1 %not_null)
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
 define i1 @t4_commutability1(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t4_commutability1(
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
@@ -146,6 +256,27 @@ define i1 @t4_commutability1(i8 %base, i8 %offset) {
   %r = and i1 %no_underflow, %not_null ; swapped
   ret i1 %r
 }
+
+define i1 @t4_commutability1_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t4_commutability1_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %adjusted = sub i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %no_underflow = icmp uge i8 %base, %offset
+  call void @use1(i1 %no_underflow)
+  %not_null = icmp ne i8 %adjusted, 0
+  call void @use1(i1 %not_null)
+  %r = select i1 %no_underflow, i1 %not_null, i1 false ; swapped
+  ret i1 %r
+}
 define i1 @t5_commutability2(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t5_commutability2(
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
@@ -167,6 +298,27 @@ define i1 @t5_commutability2(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t5_commutability2_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t5_commutability2_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %adjusted = sub i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %no_underflow = icmp ule i8 %offset, %base ; swapped
+  call void @use1(i1 %no_underflow)
+  %not_null = icmp ne i8 %adjusted, 0
+  call void @use1(i1 %not_null)
+  %r = select i1 %no_underflow, i1 %not_null, i1 false ; swapped
+  ret i1 %r
+}
+
 define i1 @t6_commutability(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t6_commutability(
 ; CHECK-NEXT:    [[AGG:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[BASE:%.*]], i8 [[OFFSET:%.*]])
@@ -194,6 +346,33 @@ define i1 @t6_commutability(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t6_commutability_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t6_commutability_logical(
+; CHECK-NEXT:    [[AGG:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[BASE:%.*]], i8 [[OFFSET:%.*]])
+; CHECK-NEXT:    call void @useagg({ i8, i1 } [[AGG]])
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = extractvalue { i8, i1 } [[AGG]], 0
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[UNDERFLOW:%.*]] = extractvalue { i8, i1 } [[AGG]], 1
+; CHECK-NEXT:    call void @use1(i1 [[UNDERFLOW]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = xor i1 [[UNDERFLOW]], true
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %agg = call {i8, i1} @llvm.usub.with.overflow(i8 %base, i8 %offset)
+  call void @useagg({i8, i1} %agg)
+  %adjusted = extractvalue {i8, i1} %agg, 0
+  call void @use8(i8 %adjusted)
+  %underflow = extractvalue {i8, i1} %agg, 1
+  call void @use1(i1 %underflow)
+  %no_underflow = xor i1 %underflow, -1
+  call void @use1(i1 %no_underflow)
+  %not_null = icmp ne i8 %adjusted, 0
+  %r = select i1 %no_underflow, i1 %not_null, i1 false ; swapped
+  ret i1 %r
+}
+
 ; What if we were checking the opposite question, that we either got null,
 ; or overflow happened?
 
@@ -217,6 +396,27 @@ define i1 @t7(i8 %base, i8 %offset) {
   %r = or i1 %null, %underflow
   ret i1 %r
 }
+
+define i1 @t7_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t7_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[UNDERFLOW:%.*]] = icmp ult i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    call void @use1(i1 [[UNDERFLOW]])
+; CHECK-NEXT:    [[NULL:%.*]] = icmp eq i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NULL]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %adjusted = sub i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %underflow = icmp ult i8 %base, %offset
+  call void @use1(i1 %underflow)
+  %null = icmp eq i8 %adjusted, 0
+  call void @use1(i1 %null)
+  %r = select i1 %null, i1 true, i1 %underflow
+  ret i1 %r
+}
 define i1 @t7_nonstrict(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t7_nonstrict(
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
@@ -237,6 +437,26 @@ define i1 @t7_nonstrict(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t7_nonstrict_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t7_nonstrict_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[UNDERFLOW:%.*]] = icmp ule i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    call void @use1(i1 [[UNDERFLOW]])
+; CHECK-NEXT:    [[NULL:%.*]] = icmp eq i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NULL]])
+; CHECK-NEXT:    ret i1 [[UNDERFLOW]]
+;
+  %adjusted = sub i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %underflow = icmp ule i8 %base, %offset ; same is valid for non-strict predicate
+  call void @use1(i1 %underflow)
+  %null = icmp eq i8 %adjusted, 0
+  call void @use1(i1 %null)
+  %r = select i1 %null, i1 true, i1 %underflow
+  ret i1 %r
+}
+
 define i1 @t8(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @t8(
 ; CHECK-NEXT:    [[AGG:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[BASE:%.*]], i8 [[OFFSET:%.*]])
@@ -260,6 +480,29 @@ define i1 @t8(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t8_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t8_logical(
+; CHECK-NEXT:    [[AGG:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[BASE:%.*]], i8 [[OFFSET:%.*]])
+; CHECK-NEXT:    call void @useagg({ i8, i1 } [[AGG]])
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = extractvalue { i8, i1 } [[AGG]], 0
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[UNDERFLOW:%.*]] = extractvalue { i8, i1 } [[AGG]], 1
+; CHECK-NEXT:    call void @use1(i1 [[UNDERFLOW]])
+; CHECK-NEXT:    [[NULL:%.*]] = icmp eq i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[NULL]], [[UNDERFLOW]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %agg = call {i8, i1} @llvm.usub.with.overflow(i8 %base, i8 %offset)
+  call void @useagg({i8, i1} %agg)
+  %adjusted = extractvalue {i8, i1} %agg, 0
+  call void @use8(i8 %adjusted)
+  %underflow = extractvalue {i8, i1} %agg, 1
+  call void @use1(i1 %underflow)
+  %null = icmp eq i8 %adjusted, 0
+  %r = select i1 %null, i1 true, i1 %underflow
+  ret i1 %r
+}
+
 ; And these patterns also have commutative variants
 
 define i1 @t9_commutative(i8 %base, i8 %offset) {
@@ -283,6 +526,27 @@ define i1 @t9_commutative(i8 %base, i8 %offset) {
   ret i1 %r
 }
 
+define i1 @t9_commutative_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @t9_commutative_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[UNDERFLOW:%.*]] = icmp ult i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    call void @use1(i1 [[UNDERFLOW]])
+; CHECK-NEXT:    [[NULL:%.*]] = icmp eq i8 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NULL]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %adjusted = sub i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %underflow = icmp ult i8 %base, %adjusted ; swapped
+  call void @use1(i1 %underflow)
+  %null = icmp eq i8 %adjusted, 0
+  call void @use1(i1 %null)
+  %r = select i1 %null, i1 true, i1 %underflow
+  ret i1 %r
+}
+
 ;-------------------------------------------------------------------------------
 
 define i1 @t10(i64 %base, i64* nonnull %offsetptr) {
@@ -308,6 +572,30 @@ define i1 @t10(i64 %base, i64* nonnull %offsetptr) {
   %r = and i1 %not_null, %no_underflow
   ret i1 %r
 }
+
+define i1 @t10_logical(i64 %base, i64* nonnull %offsetptr) {
+; CHECK-LABEL: @t10_logical(
+; CHECK-NEXT:    [[OFFSET:%.*]] = ptrtoint i64* [[OFFSETPTR:%.*]] to i64
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i64 [[BASE:%.*]], [[OFFSET]]
+; CHECK-NEXT:    call void @use64(i64 [[ADJUSTED]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ule i64 [[OFFSET]], [[BASE]]
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i64 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i64 [[OFFSET]], [[BASE]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %offset = ptrtoint i64* %offsetptr to i64
+
+  %adjusted = sub i64 %base, %offset
+  call void @use64(i64 %adjusted)
+  %no_underflow = icmp ult i64 %adjusted, %base
+  call void @use1(i1 %no_underflow)
+  %not_null = icmp ne i64 %adjusted, 0
+  call void @use1(i1 %not_null)
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
 define i1 @t11_commutative(i64 %base, i64* nonnull %offsetptr) {
 ; CHECK-LABEL: @t11_commutative(
 ; CHECK-NEXT:    [[OFFSET:%.*]] = ptrtoint i64* [[OFFSETPTR:%.*]] to i64
@@ -332,6 +620,30 @@ define i1 @t11_commutative(i64 %base, i64* nonnull %offsetptr) {
   ret i1 %r
 }
 
+define i1 @t11_commutative_logical(i64 %base, i64* nonnull %offsetptr) {
+; CHECK-LABEL: @t11_commutative_logical(
+; CHECK-NEXT:    [[OFFSET:%.*]] = ptrtoint i64* [[OFFSETPTR:%.*]] to i64
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i64 [[BASE:%.*]], [[OFFSET]]
+; CHECK-NEXT:    call void @use64(i64 [[ADJUSTED]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ule i64 [[OFFSET]], [[BASE]]
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i64 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i64 [[OFFSET]], [[BASE]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %offset = ptrtoint i64* %offsetptr to i64
+
+  %adjusted = sub i64 %base, %offset
+  call void @use64(i64 %adjusted)
+  %no_underflow = icmp ugt i64 %base, %adjusted ; swapped
+  call void @use1(i1 %no_underflow)
+  %not_null = icmp ne i64 %adjusted, 0
+  call void @use1(i1 %not_null)
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
+
 define i1 @t12(i64 %base, i64* nonnull %offsetptr) {
 ; CHECK-LABEL: @t12(
 ; CHECK-NEXT:    [[OFFSET:%.*]] = ptrtoint i64* [[OFFSETPTR:%.*]] to i64
@@ -355,6 +667,30 @@ define i1 @t12(i64 %base, i64* nonnull %offsetptr) {
   %r = or i1 %not_null, %no_underflow
   ret i1 %r
 }
+
+define i1 @t12_logical(i64 %base, i64* nonnull %offsetptr) {
+; CHECK-LABEL: @t12_logical(
+; CHECK-NEXT:    [[OFFSET:%.*]] = ptrtoint i64* [[OFFSETPTR:%.*]] to i64
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i64 [[BASE:%.*]], [[OFFSET]]
+; CHECK-NEXT:    call void @use64(i64 [[ADJUSTED]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ugt i64 [[OFFSET]], [[BASE]]
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp eq i64 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp uge i64 [[OFFSET]], [[BASE]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %offset = ptrtoint i64* %offsetptr to i64
+
+  %adjusted = sub i64 %base, %offset
+  call void @use64(i64 %adjusted)
+  %no_underflow = icmp uge i64 %adjusted, %base
+  call void @use1(i1 %no_underflow)
+  %not_null = icmp eq i64 %adjusted, 0
+  call void @use1(i1 %not_null)
+  %r = select i1 %not_null, i1 true, i1 %no_underflow
+  ret i1 %r
+}
 define i1 @t13(i64 %base, i64* nonnull %offsetptr) {
 ; CHECK-LABEL: @t13(
 ; CHECK-NEXT:    [[OFFSET:%.*]] = ptrtoint i64* [[OFFSETPTR:%.*]] to i64
@@ -379,6 +715,30 @@ define i1 @t13(i64 %base, i64* nonnull %offsetptr) {
   ret i1 %r
 }
 
+define i1 @t13_logical(i64 %base, i64* nonnull %offsetptr) {
+; CHECK-LABEL: @t13_logical(
+; CHECK-NEXT:    [[OFFSET:%.*]] = ptrtoint i64* [[OFFSETPTR:%.*]] to i64
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i64 [[BASE:%.*]], [[OFFSET]]
+; CHECK-NEXT:    call void @use64(i64 [[ADJUSTED]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ugt i64 [[OFFSET]], [[BASE]]
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp eq i64 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp uge i64 [[OFFSET]], [[BASE]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %offset = ptrtoint i64* %offsetptr to i64
+
+  %adjusted = sub i64 %base, %offset
+  call void @use64(i64 %adjusted)
+  %no_underflow = icmp ule i64 %base, %adjusted ; swapped
+  call void @use1(i1 %no_underflow)
+  %not_null = icmp eq i64 %adjusted, 0
+  call void @use1(i1 %not_null)
+  %r = select i1 %not_null, i1 true, i1 %no_underflow
+  ret i1 %r
+}
+
 define i1 @t14_bad(i64 %base, i64 %offset) {
 ; CHECK-LABEL: @t14_bad(
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i64 [[BASE:%.*]], [[OFFSET:%.*]]
@@ -400,6 +760,27 @@ define i1 @t14_bad(i64 %base, i64 %offset) {
   ret i1 %r
 }
 
+define i1 @t14_bad_logical(i64 %base, i64 %offset) {
+; CHECK-LABEL: @t14_bad_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i64 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use64(i64 [[ADJUSTED]])
+; CHECK-NEXT:    [[NO_UNDERFLOW:%.*]] = icmp ult i64 [[ADJUSTED]], [[BASE]]
+; CHECK-NEXT:    call void @use1(i1 [[NO_UNDERFLOW]])
+; CHECK-NEXT:    [[NOT_NULL:%.*]] = icmp ne i64 [[ADJUSTED]], 0
+; CHECK-NEXT:    call void @use1(i1 [[NOT_NULL]])
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOT_NULL]], [[NO_UNDERFLOW]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %adjusted = sub i64 %base, %offset
+  call void @use64(i64 %adjusted)
+  %no_underflow = icmp ult i64 %adjusted, %base
+  call void @use1(i1 %no_underflow)
+  %not_null = icmp ne i64 %adjusted, 0
+  call void @use1(i1 %not_null)
+  %r = select i1 %not_null, i1 %no_underflow, i1 false
+  ret i1 %r
+}
+
 define i1 @base_ult_offset(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @base_ult_offset(
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
@@ -414,6 +795,21 @@ define i1 @base_ult_offset(i8 %base, i8 %offset) {
   %r = and i1 %no_underflow, %not_null
   ret i1 %r
 }
+
+define i1 @base_ult_offset_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @base_ult_offset_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %adjusted = sub i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp ne i8 %adjusted, 0
+  %no_underflow = icmp ule i8 %base, %offset
+  %r = select i1 %no_underflow, i1 %not_null, i1 false
+  ret i1 %r
+}
 define i1 @base_uge_offset(i8 %base, i8 %offset) {
 ; CHECK-LABEL: @base_uge_offset(
 ; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
@@ -428,3 +824,18 @@ define i1 @base_uge_offset(i8 %base, i8 %offset) {
   %r = or i1 %no_underflow, %not_null
   ret i1 %r
 }
+
+define i1 @base_uge_offset_logical(i8 %base, i8 %offset) {
+; CHECK-LABEL: @base_uge_offset_logical(
+; CHECK-NEXT:    [[ADJUSTED:%.*]] = sub i8 [[BASE:%.*]], [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @use8(i8 [[ADJUSTED]])
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp uge i8 [[BASE]], [[OFFSET]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %adjusted = sub i8 %base, %offset
+  call void @use8(i8 %adjusted)
+  %not_null = icmp eq i8 %adjusted, 0
+  %no_underflow = icmp ugt i8 %base, %offset
+  %r = select i1 %no_underflow, i1 true, i1 %not_null
+  ret i1 %r
+}

diff  --git a/llvm/test/Transforms/InstCombine/select-crash-noverify.ll b/llvm/test/Transforms/InstCombine/select-crash-noverify.ll
index 4a366aa8fb83..aa018db5076c 100644
--- a/llvm/test/Transforms/InstCombine/select-crash-noverify.ll
+++ b/llvm/test/Transforms/InstCombine/select-crash-noverify.ll
@@ -17,3 +17,19 @@ xpto:
 return:
   ret i32 7
 }
+
+define i32 @test3_logical(i1 %bool, i32 %a) {
+entry:
+  %cond = select i1 %bool, i1 true, i1 true
+  br i1 %cond, label %return, label %xpto
+
+; technically reachable, but this malformed IR may appear as a result of constant propagation
+xpto:
+  %select = select i1 %bool, i32 %a, i32 %select
+  %select2 = select i1 %bool, i32 %select2, i32 %a
+  %sum = add i32 %select, %select2
+  ret i32 %sum
+
+return:
+  ret i32 7
+}

diff  --git a/llvm/test/Transforms/InstCombine/select-ctlz-to-cttz.ll b/llvm/test/Transforms/InstCombine/select-ctlz-to-cttz.ll
index c534acd70cdb..64b16905fb97 100644
--- a/llvm/test/Transforms/InstCombine/select-ctlz-to-cttz.ll
+++ b/llvm/test/Transforms/InstCombine/select-ctlz-to-cttz.ll
@@ -16,7 +16,7 @@ declare void @use2(i1)
 
 define i32 @select_clz_to_ctz(i32 %a) {
 ; CHECK-LABEL: @select_clz_to_ctz(
-; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 true), !range !0
+; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 true), [[RNG0:!range !.*]]
 ; CHECK-NEXT:    ret i32 [[COND]]
 ;
   %sub = sub i32 0, %a
@@ -30,7 +30,7 @@ define i32 @select_clz_to_ctz(i32 %a) {
 
 define i32 @select_clz_to_ctz_preserve_flag(i32 %a) {
 ; CHECK-LABEL: @select_clz_to_ctz_preserve_flag(
-; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 false), !range !0
+; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 false), [[RNG0]]
 ; CHECK-NEXT:    ret i32 [[COND]]
 ;
   %sub = sub i32 0, %a
@@ -60,10 +60,10 @@ define i32 @select_clz_to_ctz_extra_use(i32 %a) {
 ; CHECK-LABEL: @select_clz_to_ctz_extra_use(
 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 0, [[A:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[A]]
-; CHECK-NEXT:    [[LZ:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[AND]], i1 true), !range !0
+; CHECK-NEXT:    [[LZ:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[AND]], i1 true), [[RNG0]]
 ; CHECK-NEXT:    [[SUB1:%.*]] = xor i32 [[LZ]], 31
 ; CHECK-NEXT:    call void @use(i32 [[SUB1]])
-; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.cttz.i32(i32 [[A]], i1 true), !range !0
+; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.cttz.i32(i32 [[A]], i1 true), [[RNG0]]
 ; CHECK-NEXT:    ret i32 [[COND]]
 ;
   %sub = sub i32 0, %a
@@ -78,7 +78,7 @@ define i32 @select_clz_to_ctz_extra_use(i32 %a) {
 
 define i32 @select_clz_to_ctz_and_commuted(i32 %a) {
 ; CHECK-LABEL: @select_clz_to_ctz_and_commuted(
-; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 true), !range !0
+; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.cttz.i32(i32 [[A:%.*]], i1 true), [[RNG0]]
 ; CHECK-NEXT:    ret i32 [[COND]]
 ;
   %sub = sub i32 0, %a
@@ -94,7 +94,7 @@ define i32 @select_clz_to_ctz_icmp_ne(i32 %a) {
 ; CHECK-LABEL: @select_clz_to_ctz_icmp_ne(
 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[A:%.*]], 0
 ; CHECK-NEXT:    call void @use2(i1 [[TOBOOL]])
-; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.cttz.i32(i32 [[A]], i1 true), !range !0
+; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.cttz.i32(i32 [[A]], i1 true), [[RNG0]]
 ; CHECK-NEXT:    ret i32 [[COND]]
 ;
   %sub = sub i32 0, %a
@@ -109,7 +109,7 @@ define i32 @select_clz_to_ctz_icmp_ne(i32 %a) {
 
 define i64 @select_clz_to_ctz_i64(i64 %a) {
 ; CHECK-LABEL: @select_clz_to_ctz_i64(
-; CHECK-NEXT:    [[COND:%.*]] = call i64 @llvm.cttz.i64(i64 [[A:%.*]], i1 true), !range !1
+; CHECK-NEXT:    [[COND:%.*]] = call i64 @llvm.cttz.i64(i64 [[A:%.*]], i1 true), [[RNG1:!range !.*]]
 ; CHECK-NEXT:    ret i64 [[COND]]
 ;
   %sub = sub i64 0, %a
@@ -127,7 +127,7 @@ define i32 @select_clz_to_ctz_wrong_sub(i32 %a) {
 ; CHECK-LABEL: @select_clz_to_ctz_wrong_sub(
 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 1, [[A:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[A]]
-; CHECK-NEXT:    [[LZ:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[AND]], i1 true), !range !0
+; CHECK-NEXT:    [[LZ:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[AND]], i1 true), [[RNG0]]
 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0
 ; CHECK-NEXT:    [[SUB1:%.*]] = xor i32 [[LZ]], 31
 ; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[LZ]], i32 [[SUB1]]
@@ -146,7 +146,7 @@ define i64 @select_clz_to_ctz_i64_wrong_xor(i64 %a) {
 ; CHECK-LABEL: @select_clz_to_ctz_i64_wrong_xor(
 ; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[A:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i64 [[SUB]], [[A]]
-; CHECK-NEXT:    [[LZ:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[AND]], i1 true), !range !1
+; CHECK-NEXT:    [[LZ:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[AND]], i1 true), [[RNG1]]
 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[A]], 0
 ; CHECK-NEXT:    [[SUB11:%.*]] = or i64 [[LZ]], 64
 ; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[LZ]], i64 [[SUB11]]
@@ -165,7 +165,7 @@ define i64 @select_clz_to_ctz_i64_wrong_icmp_cst(i64 %a) {
 ; CHECK-LABEL: @select_clz_to_ctz_i64_wrong_icmp_cst(
 ; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[A:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i64 [[SUB]], [[A]]
-; CHECK-NEXT:    [[LZ:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[AND]], i1 true), !range !1
+; CHECK-NEXT:    [[LZ:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[AND]], i1 true), [[RNG1]]
 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[A]], 1
 ; CHECK-NEXT:    [[SUB1:%.*]] = xor i64 [[LZ]], 63
 ; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[LZ]], i64 [[SUB1]]
@@ -184,7 +184,7 @@ define i64 @select_clz_to_ctz_i64_wrong_icmp_pred(i64 %a) {
 ; CHECK-LABEL: @select_clz_to_ctz_i64_wrong_icmp_pred(
 ; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[A:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i64 [[SUB]], [[A]]
-; CHECK-NEXT:    [[LZ:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[AND]], i1 true), !range !1
+; CHECK-NEXT:    [[LZ:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[AND]], i1 true), [[RNG1]]
 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp slt i64 [[A]], 0
 ; CHECK-NEXT:    [[SUB1:%.*]] = xor i64 [[LZ]], 63
 ; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[LZ]], i64 [[SUB1]]
@@ -220,11 +220,11 @@ define <2 x i32> @select_clz_to_ctz_vec_with_undef(<2 x i32> %a) {
 
 define i4 @PR45762(i3 %x4) {
 ; CHECK-LABEL: @PR45762(
-; CHECK-NEXT:    [[T4:%.*]] = call i3 @llvm.cttz.i3(i3 [[X4:%.*]], i1 false), !range !2
+; CHECK-NEXT:    [[T4:%.*]] = call i3 @llvm.cttz.i3(i3 [[X4:%.*]], i1 false), [[RNG2:!range !.*]]
 ; CHECK-NEXT:    [[T7:%.*]] = zext i3 [[T4]] to i4
 ; CHECK-NEXT:    [[ONE_HOT_16:%.*]] = shl i4 1, [[T7]]
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i3 [[X4]], 0
-; CHECK-NEXT:    [[UMUL_23:%.*]] = select i1 [[TMP1]], i4 0, i4 [[T7]]
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i3 [[X4]], 0
+; CHECK-NEXT:    [[UMUL_23:%.*]] = select i1 [[DOTNOT]], i4 0, i4 [[T7]]
 ; CHECK-NEXT:    [[SEL_71:%.*]] = shl i4 [[ONE_HOT_16]], [[UMUL_23]]
 ; CHECK-NEXT:    ret i4 [[SEL_71]]
 ;
@@ -246,3 +246,32 @@ define i4 @PR45762(i3 %x4) {
   %sel_71 = select i1 %t12, i4 %one_hot_16, i4 %umul_23
   ret i4 %sel_71
 }
+
+define i4 @PR45762_logical(i3 %x4) {
+; CHECK-LABEL: @PR45762_logical(
+; CHECK-NEXT:    [[T4:%.*]] = call i3 @llvm.cttz.i3(i3 [[X4:%.*]], i1 false), [[RNG2]]
+; CHECK-NEXT:    [[T7:%.*]] = zext i3 [[T4]] to i4
+; CHECK-NEXT:    [[ONE_HOT_16:%.*]] = shl i4 1, [[T7]]
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i3 [[X4]], 0
+; CHECK-NEXT:    [[UMUL_23:%.*]] = select i1 [[DOTNOT]], i4 0, i4 [[T7]]
+; CHECK-NEXT:    [[SEL_71:%.*]] = shl i4 [[ONE_HOT_16]], [[UMUL_23]]
+; CHECK-NEXT:    ret i4 [[SEL_71]]
+;
+  %t4 = call i3 @llvm.cttz.i3(i3 %x4, i1 false)
+  %t5 = icmp eq i3 %x4, 0
+  %t6 = select i1 %t5, i3 3, i3 %t4
+  %t7 = zext i3 %t6 to i4
+  %one_hot_16 = shl i4 1, %t7
+  %t8 = lshr i4 %one_hot_16, 0
+  %bit_slice_61 = trunc i4 %t8 to i1
+  %t9 = lshr i4 %one_hot_16, 1
+  %bit_slice_62 = trunc i4 %t9 to i1
+  %t10 = lshr i4 %one_hot_16, 2
+  %bit_slice_64 = trunc i4 %t10 to i1
+  %t11 = select i1 %bit_slice_61, i1 true, i1 %bit_slice_62
+  %or_69 = select i1 %t11, i1 true, i1 %bit_slice_64
+  %umul_23 = mul i4 %one_hot_16, %one_hot_16
+  %t12 = icmp eq i1 %or_69, false
+  %sel_71 = select i1 %t12, i4 %one_hot_16, i4 %umul_23
+  ret i4 %sel_71
+}

diff  --git a/llvm/test/Transforms/InstCombine/select-imm-canon.ll b/llvm/test/Transforms/InstCombine/select-imm-canon.ll
index 272d4a47ce68..e230b3b92777 100644
--- a/llvm/test/Transforms/InstCombine/select-imm-canon.ll
+++ b/llvm/test/Transforms/InstCombine/select-imm-canon.ll
@@ -5,9 +5,9 @@ define i8 @single(i32 %A) {
 ; CHECK-LABEL: @single(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[A:%.*]], -128
-; CHECK-NEXT:    [[L2:%.*]] = select i1 [[TMP0]], i32 [[A]], i32 -128
-; CHECK-NEXT:    [[CONV7:%.*]] = trunc i32 [[L2]] to i8
-; CHECK-NEXT:    ret i8 [[CONV7]]
+; CHECK-NEXT:    [[CONV71:%.*]] = select i1 [[TMP0]], i32 [[A]], i32 -128
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[CONV71]] to i8
+; CHECK-NEXT:    ret i8 [[TMP1]]
 ;
 entry:
   %l1 = icmp slt i32 %A, -128
@@ -20,11 +20,11 @@ define i8 @double(i32 %A) {
 ; CHECK-LABEL: @double(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[A:%.*]], -128
-; CHECK-NEXT:    [[L2:%.*]] = select i1 [[TMP0]], i32 [[A]], i32 -128
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[L2]], 127
-; CHECK-NEXT:    [[SPEC_SELECT_I:%.*]] = select i1 [[TMP1]], i32 [[L2]], i32 127
-; CHECK-NEXT:    [[CONV7:%.*]] = trunc i32 [[SPEC_SELECT_I]] to i8
-; CHECK-NEXT:    ret i8 [[CONV7]]
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[TMP0]], i32 [[A]], i32 -128
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 127
+; CHECK-NEXT:    [[CONV71:%.*]] = select i1 [[TMP2]], i32 [[TMP1]], i32 127
+; CHECK-NEXT:    [[TMP3:%.*]] = trunc i32 [[CONV71]] to i8
+; CHECK-NEXT:    ret i8 [[TMP3]]
 ;
 entry:
   %l1 = icmp slt i32 %A, -128
@@ -68,3 +68,22 @@ define i8 @original(i32 %A, i32 %B) {
   %conv7 = trunc i32 %spec.select.i to i8
   ret i8 %conv7
 }
+
+define i8 @original_logical(i32 %A, i32 %B) {
+; CHECK-LABEL: @original_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], -128
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[A]], i32 -128
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 127
+; CHECK-NEXT:    [[SPEC_SELECT_I:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 127
+; CHECK-NEXT:    [[CONV7:%.*]] = trunc i32 [[SPEC_SELECT_I]] to i8
+; CHECK-NEXT:    ret i8 [[CONV7]]
+;
+  %cmp4.i = icmp slt i32 127, %A
+  %cmp6.i = icmp sle i32 -128, %A
+  %retval.0.i = select i1 %cmp4.i, i32 127, i32 -128
+  %not.cmp4.i = xor i1 %cmp4.i, true
+  %cleanup.dest.slot.0.i = select i1 %cmp6.i, i1 %not.cmp4.i, i1 false
+  %spec.select.i = select i1 %cleanup.dest.slot.0.i, i32 %A, i32 %retval.0.i
+  %conv7 = trunc i32 %spec.select.i to i8
+  ret i8 %conv7
+}

diff  --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 819ac6dd3a82..d603de371ba0 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -70,7 +70,7 @@ define <2 x i1> @test8vec(<2 x i1> %C, <2 x i1> %X) {
 
 define <vscale x 2 x i1> @test8vvec(<vscale x 2 x i1> %C, <vscale x 2 x i1> %X) {
 ; CHECK-LABEL: @test8vvec(
-; CHECK-NEXT:    [[R:%.*]] = and <vscale x 2 x i1> [[C:%.*]],  [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = and <vscale x 2 x i1> [[C:%.*]], [[X:%.*]]
 ; CHECK-NEXT:    ret <vscale x 2 x i1> [[R]]
 ;
   %R = select <vscale x 2 x i1> %C, <vscale x 2 x i1> %X, <vscale x 2 x i1> zeroinitializer
@@ -501,6 +501,27 @@ ret:
   ret i32 %b
 }
 
+define i32 @test26_logical(i1 %cond)  {
+; CHECK-LABEL: @test26_logical(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[COND:%.*]], label [[JUMP:%.*]], label [[RET:%.*]]
+; CHECK:       jump:
+; CHECK-NEXT:    br label [[RET]]
+; CHECK:       ret:
+; CHECK-NEXT:    [[B:%.*]] = phi i32 [ 10, [[JUMP]] ], [ 20, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    ret i32 [[B]]
+;
+entry:
+  br i1 %cond, label %jump, label %ret
+jump:
+  %c = select i1 false, i1 true, i1 false
+  br label %ret
+ret:
+  %a = phi i1 [true, %entry], [%c, %jump]
+  %b = select i1 %a, i32 20, i32 10
+  ret i32 %b
+}
+
 define i32 @test27(i1 %c, i32 %A, i32 %B)  {
 ; CHECK-LABEL: @test27(
 ; CHECK-NEXT:  entry:
@@ -720,9 +741,9 @@ define i48 @test51(<3 x i1> %icmp, <3 x i16> %tmp) {
 
 define <vscale x 4 x float> @bitcast_select_bitcast(<vscale x 4 x i1> %icmp, <vscale x 4 x i32> %a, <vscale x 4 x float> %b) {
 ; CHECK-LABEL: @bitcast_select_bitcast(
-; CHECK-NEXT:    [[BC1:%.*]] = bitcast <vscale x 4 x i32> [[A:%.*]] to <vscale x 4 x float>
-; CHECK-NEXT:    [[SELECT:%.*]] = select <vscale x 4 x i1> [[ICMP:%.*]], <vscale x 4 x float> [[B:%.*]], <vscale x 4 x float> [[BC1]]
-; CHECK-NEXT:    ret <vscale x 4 x float> [[SELECT]]
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <vscale x 4 x i32> [[A:%.*]] to <vscale x 4 x float>
+; CHECK-NEXT:    [[BC2:%.*]] = select <vscale x 4 x i1> [[ICMP:%.*]], <vscale x 4 x float> [[B:%.*]], <vscale x 4 x float> [[TMP1]]
+; CHECK-NEXT:    ret <vscale x 4 x float> [[BC2]]
 ;
   %bc1 = bitcast <vscale x 4 x float> %b to <vscale x 4 x i32>
   %select = select <vscale x 4 x i1> %icmp, <vscale x 4 x i32> %bc1, <vscale x 4 x i32> %a

diff  --git a/llvm/test/Transforms/InstCombine/set.ll b/llvm/test/Transforms/InstCombine/set.ll
index b8c349aaf94e..bc2cdb7c469e 100644
--- a/llvm/test/Transforms/InstCombine/set.ll
+++ b/llvm/test/Transforms/InstCombine/set.ll
@@ -15,6 +15,17 @@ define i1 @test1(i32 %A) {
   ret i1 %D
 }
 
+define i1 @test1_logical(i32 %A) {
+; CHECK-LABEL: @test1_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %B = icmp eq i32 %A, %A
+  ; Never true
+  %C = icmp eq i32* @X, null
+  %D = select i1 %B, i1 %C, i1 false
+  ret i1 %D
+}
+
 define i1 @test2(i32 %A) {
 ; CHECK-LABEL: @test2(
 ; CHECK-NEXT:    ret i1 true
@@ -26,6 +37,17 @@ define i1 @test2(i32 %A) {
   ret i1 %D
 }
 
+define i1 @test2_logical(i32 %A) {
+; CHECK-LABEL: @test2_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %B = icmp ne i32 %A, %A
+  ; Never false
+  %C = icmp ne i32* @X, null
+  %D = select i1 %B, i1 true, i1 %C
+  ret i1 %D
+}
+
 define i1 @test3(i32 %A) {
 ; CHECK-LABEL: @test3(
 ; CHECK-NEXT:    ret i1 false
@@ -160,6 +182,18 @@ define i1 @bool_eq0(i64 %a) {
   ret i1 %and
 }
 
+define i1 @bool_eq0_logical(i64 %a) {
+; CHECK-LABEL: @bool_eq0_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[A:%.*]], 1
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %b = icmp sgt i64 %a, 0
+  %c = icmp eq i64 %a, 1
+  %notc = icmp eq i1 %c, false
+  %and = select i1 %b, i1 %notc, i1 false
+  ret i1 %and
+}
+
 ; This is equivalent to the previous test.
 
 define i1 @xor_of_icmps(i64 %a) {
@@ -207,8 +241,8 @@ define i32 @PR2844(i32 %x) {
 ; CHECK-LABEL: @PR2844(
 ; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
 ; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[X]], -638208502
-; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[A]], [[B]]
-; CHECK-NEXT:    [[SEL:%.*]] = zext i1 [[TMP1]] to i32
+; CHECK-NEXT:    [[NOT_OR:%.*]] = and i1 [[A]], [[B]]
+; CHECK-NEXT:    [[SEL:%.*]] = zext i1 [[NOT_OR]] to i32
 ; CHECK-NEXT:    ret i32 [[SEL]]
 ;
   %A = icmp eq i32 %x, 0
@@ -218,6 +252,21 @@ define i32 @PR2844(i32 %x) {
   ret i32 %sel
 }
 
+define i32 @PR2844_logical(i32 %x) {
+; CHECK-LABEL: @PR2844_logical(
+; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
+; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[X]], -638208502
+; CHECK-NEXT:    [[NOT_OR:%.*]] = and i1 [[A]], [[B]]
+; CHECK-NEXT:    [[SEL:%.*]] = zext i1 [[NOT_OR]] to i32
+; CHECK-NEXT:    ret i32 [[SEL]]
+;
+  %A = icmp eq i32 %x, 0
+  %B = icmp slt i32 %x, -638208501
+  %or = select i1 %A, i1 true, i1 %B
+  %sel = select i1 %or, i32 0, i32 1
+  ret i32 %sel
+}
+
 define i1 @test16(i32 %A) {
 ; CHECK-LABEL: @test16(
 ; CHECK-NEXT:    ret i1 false
@@ -284,8 +333,8 @@ define i32 @test20(i32 %A) {
 
 define <2 x i32> @test20vec(<2 x i32> %A) {
 ; CHECK-LABEL: @test20vec(
-; CHECK-NEXT:    [[B:%.*]] = and <2 x i32> [[A:%.*]], <i32 1, i32 1>
-; CHECK-NEXT:    ret <2 x i32> [[B]]
+; CHECK-NEXT:    [[D:%.*]] = and <2 x i32> [[A:%.*]], <i32 1, i32 1>
+; CHECK-NEXT:    ret <2 x i32> [[D]]
 ;
   %B = and <2 x i32> %A, <i32 1, i32 1>
   %C = icmp ne <2 x i32> %B, zeroinitializer
@@ -329,6 +378,18 @@ define i1 @test22(i32 %A, i32 %X) {
   ret i1 %R
 }
 
+define i1 @test22_logical(i32 %A, i32 %X) {
+; CHECK-LABEL: @test22_logical(
+; CHECK-NEXT:    ret i1 true
+;
+  %B = and i32 %A, 100663295
+  %C = icmp ult i32 %B, 268435456
+  %Y = and i32 %X, 7
+  %Z = icmp sgt i32 %Y, -1
+  %R = select i1 %C, i1 true, i1 %Z
+  ret i1 %R
+}
+
 define i32 @test23(i32 %a) {
 ; CHECK-LABEL: @test23(
 ; CHECK-NEXT:    [[TMP_1:%.*]] = and i32 [[A:%.*]], 1
@@ -355,10 +416,10 @@ define <2 x i32> @test23vec(<2 x i32> %a) {
 
 define i32 @test24(i32 %a) {
 ; CHECK-LABEL: @test24(
-; CHECK-NEXT:    [[TMP_1:%.*]] = lshr i32 [[A:%.*]], 2
-; CHECK-NEXT:    [[TMP_1_LOBIT:%.*]] = and i32 [[TMP_1]], 1
-; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[TMP_1_LOBIT]], 1
-; CHECK-NEXT:    ret i32 [[TMP1]]
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[A:%.*]], 2
+; CHECK-NEXT:    [[DOTLOBIT:%.*]] = and i32 [[TMP1]], 1
+; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[DOTLOBIT]], 1
+; CHECK-NEXT:    ret i32 [[TMP2]]
 ;
   %tmp1 = and i32 %a, 4
   %tmp.1 = lshr i32 %tmp1, 2
@@ -369,10 +430,10 @@ define i32 @test24(i32 %a) {
 
 define <2 x i32> @test24vec(<2 x i32> %a) {
 ; CHECK-LABEL: @test24vec(
-; CHECK-NEXT:    [[TMP_1:%.*]] = lshr <2 x i32> [[A:%.*]], <i32 2, i32 2>
-; CHECK-NEXT:    [[TMP_1_LOBIT:%.*]] = and <2 x i32> [[TMP_1]], <i32 1, i32 1>
-; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[TMP_1_LOBIT]], <i32 1, i32 1>
-; CHECK-NEXT:    ret <2 x i32> [[TMP1]]
+; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[A:%.*]], <i32 2, i32 2>
+; CHECK-NEXT:    [[DOTLOBIT:%.*]] = and <2 x i32> [[TMP1]], <i32 1, i32 1>
+; CHECK-NEXT:    [[TMP2:%.*]] = xor <2 x i32> [[DOTLOBIT]], <i32 1, i32 1>
+; CHECK-NEXT:    ret <2 x i32> [[TMP2]]
 ;
   %tmp1 = and <2 x i32> %a, <i32 4, i32 4>
   %tmp.1 = lshr <2 x i32> %tmp1, <i32 2, i32 2>

diff  --git a/llvm/test/Transforms/InstCombine/sign-test-and-or.ll b/llvm/test/Transforms/InstCombine/sign-test-and-or.ll
index 1920a800ef1f..a71cb54b9fc2 100644
--- a/llvm/test/Transforms/InstCombine/sign-test-and-or.ll
+++ b/llvm/test/Transforms/InstCombine/sign-test-and-or.ll
@@ -5,7 +5,7 @@ declare void @foo()
 
 define i1 @test1(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test1(
-; CHECK-NEXT:    [[TMP1:%.*]] = or i32 %a, %b
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 0
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
@@ -15,9 +15,21 @@ define i1 @test1(i32 %a, i32 %b) {
   ret i1 %or.cond
 }
 
+define i1 @test1_logical(i32 %a, i32 %b) {
+; CHECK-LABEL: @test1_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 0
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %1 = icmp slt i32 %a, 0
+  %2 = icmp slt i32 %b, 0
+  %or.cond = select i1 %1, i1 true, i1 %2
+  ret i1 %or.cond
+}
+
 define i1 @test2(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test2(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %a, %b
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], -1
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
@@ -27,9 +39,21 @@ define i1 @test2(i32 %a, i32 %b) {
   ret i1 %or.cond
 }
 
+define i1 @test2_logical(i32 %a, i32 %b) {
+; CHECK-LABEL: @test2_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], -1
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %1 = icmp sgt i32 %a, -1
+  %2 = icmp sgt i32 %b, -1
+  %or.cond = select i1 %1, i1 true, i1 %2
+  ret i1 %or.cond
+}
+
 define i1 @test3(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test3(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %a, %b
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 0
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
@@ -39,9 +63,21 @@ define i1 @test3(i32 %a, i32 %b) {
   ret i1 %or.cond
 }
 
+define i1 @test3_logical(i32 %a, i32 %b) {
+; CHECK-LABEL: @test3_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 0
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %1 = icmp slt i32 %a, 0
+  %2 = icmp slt i32 %b, 0
+  %or.cond = select i1 %1, i1 %2, i1 false
+  ret i1 %or.cond
+}
+
 define i1 @test4(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test4(
-; CHECK-NEXT:    [[TMP1:%.*]] = or i32 %a, %b
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], -1
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
@@ -51,11 +87,28 @@ define i1 @test4(i32 %a, i32 %b) {
   ret i1 %or.cond
 }
 
+define i1 @test4_logical(i32 %a, i32 %b) {
+; CHECK-LABEL: @test4_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], -1
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %1 = icmp sgt i32 %a, -1
+  %2 = icmp sgt i32 %b, -1
+  %or.cond = select i1 %1, i1 %2, i1 false
+  ret i1 %or.cond
+}
+
 define void @test5(i32 %a) {
 ; CHECK-LABEL: @test5(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %a, -2013265920
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], -2013265920
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    br i1 [[TMP2]], label %if.then, label %if.end
+; CHECK-NEXT:    br i1 [[TMP2]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    tail call void @foo() [[ATTR0:#.*]]
+; CHECK-NEXT:    ret void
+; CHECK:       if.end:
+; CHECK-NEXT:    ret void
 ;
   %and = and i32 %a, 134217728
   %1 = icmp eq i32 %and, 0
@@ -64,6 +117,32 @@ define void @test5(i32 %a) {
   br i1 %or.cond, label %if.then, label %if.end
 
 
+if.then:
+  tail call void @foo() nounwind
+  ret void
+
+if.end:
+  ret void
+}
+
+define void @test5_logical(i32 %a) {
+; CHECK-LABEL: @test5_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], -2013265920
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    br i1 [[TMP2]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    tail call void @foo() [[ATTR0]]
+; CHECK-NEXT:    ret void
+; CHECK:       if.end:
+; CHECK-NEXT:    ret void
+;
+  %and = and i32 %a, 134217728
+  %1 = icmp eq i32 %and, 0
+  %2 = icmp sgt i32 %a, -1
+  %or.cond = select i1 %1, i1 %2, i1 false
+  br i1 %or.cond, label %if.then, label %if.end
+
+
 if.then:
   tail call void @foo() nounwind
   ret void
@@ -74,9 +153,14 @@ if.end:
 
 define void @test6(i32 %a) {
 ; CHECK-LABEL: @test6(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %a, -2013265920
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], -2013265920
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    br i1 [[TMP2]], label %if.then, label %if.end
+; CHECK-NEXT:    br i1 [[TMP2]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    tail call void @foo() [[ATTR0]]
+; CHECK-NEXT:    ret void
+; CHECK:       if.end:
+; CHECK-NEXT:    ret void
 ;
   %1 = icmp sgt i32 %a, -1
   %and = and i32 %a, 134217728
@@ -85,6 +169,32 @@ define void @test6(i32 %a) {
   br i1 %or.cond, label %if.then, label %if.end
 
 
+if.then:
+  tail call void @foo() nounwind
+  ret void
+
+if.end:
+  ret void
+}
+
+define void @test6_logical(i32 %a) {
+; CHECK-LABEL: @test6_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], -2013265920
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    br i1 [[TMP2]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    tail call void @foo() [[ATTR0]]
+; CHECK-NEXT:    ret void
+; CHECK:       if.end:
+; CHECK-NEXT:    ret void
+;
+  %1 = icmp sgt i32 %a, -1
+  %and = and i32 %a, 134217728
+  %2 = icmp eq i32 %and, 0
+  %or.cond = select i1 %1, i1 %2, i1 false
+  br i1 %or.cond, label %if.then, label %if.end
+
+
 if.then:
   tail call void @foo() nounwind
   ret void
@@ -95,9 +205,14 @@ if.end:
 
 define void @test7(i32 %a) {
 ; CHECK-LABEL: @test7(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %a, -2013265920
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    br i1 [[TMP2]], label %if.end, label %if.then
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], -2013265920
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    br i1 [[DOTNOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    tail call void @foo() [[ATTR0]]
+; CHECK-NEXT:    ret void
+; CHECK:       if.end:
+; CHECK-NEXT:    ret void
 ;
   %and = and i32 %a, 134217728
   %1 = icmp ne i32 %and, 0
@@ -106,6 +221,32 @@ define void @test7(i32 %a) {
   br i1 %or.cond, label %if.then, label %if.end
 
 
+if.then:
+  tail call void @foo() nounwind
+  ret void
+
+if.end:
+  ret void
+}
+
+define void @test7_logical(i32 %a) {
+; CHECK-LABEL: @test7_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], -2013265920
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    br i1 [[DOTNOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    tail call void @foo() [[ATTR0]]
+; CHECK-NEXT:    ret void
+; CHECK:       if.end:
+; CHECK-NEXT:    ret void
+;
+  %and = and i32 %a, 134217728
+  %1 = icmp ne i32 %and, 0
+  %2 = icmp slt i32 %a, 0
+  %or.cond = select i1 %1, i1 true, i1 %2
+  br i1 %or.cond, label %if.then, label %if.end
+
+
 if.then:
   tail call void @foo() nounwind
   ret void
@@ -116,9 +257,14 @@ if.end:
 
 define void @test8(i32 %a) {
 ; CHECK-LABEL: @test8(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %a, -2013265920
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
-; CHECK-NEXT:    br i1 [[TMP2]], label %if.end, label %if.then
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], -2013265920
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    br i1 [[DOTNOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    tail call void @foo()
+; CHECK-NEXT:    ret void
+; CHECK:       if.end:
+; CHECK-NEXT:    ret void
 ;
   %1 = icmp slt i32 %a, 0
   %and = and i32 %a, 134217728
@@ -127,6 +273,32 @@ define void @test8(i32 %a) {
   br i1 %or.cond, label %if.then, label %if.end
 
 
+if.then:
+  tail call void @foo()
+  ret void
+
+if.end:
+  ret void
+}
+
+define void @test8_logical(i32 %a) {
+; CHECK-LABEL: @test8_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], -2013265920
+; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT:    br i1 [[DOTNOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; CHECK:       if.then:
+; CHECK-NEXT:    tail call void @foo()
+; CHECK-NEXT:    ret void
+; CHECK:       if.end:
+; CHECK-NEXT:    ret void
+;
+  %1 = icmp slt i32 %a, 0
+  %and = and i32 %a, 134217728
+  %2 = icmp ne i32 %and, 0
+  %or.cond = select i1 %1, i1 true, i1 %2
+  br i1 %or.cond, label %if.then, label %if.end
+
+
 if.then:
   tail call void @foo()
   ret void
@@ -137,7 +309,7 @@ if.end:
 
 define i1 @test9(i32 %a) {
 ; CHECK-LABEL: @test9(
-; CHECK-NEXT:    [[TMP1:%.*]] = and i32 %a, -1073741824
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], -1073741824
 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1073741824
 ; CHECK-NEXT:    ret i1 [[TMP2]]
 ;
@@ -148,9 +320,22 @@ define i1 @test9(i32 %a) {
   ret i1 %or.cond
 }
 
+define i1 @test9_logical(i32 %a) {
+; CHECK-LABEL: @test9_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], -1073741824
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 1073741824
+; CHECK-NEXT:    ret i1 [[TMP2]]
+;
+  %1 = and i32 %a, 1073741824
+  %2 = icmp ne i32 %1, 0
+  %3 = icmp sgt i32 %a, -1
+  %or.cond = select i1 %2, i1 %3, i1 false
+  ret i1 %or.cond
+}
+
 define i1 @test10(i32 %a) {
 ; CHECK-LABEL: @test10(
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 %a, 2
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[A:%.*]], 2
 ; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %1 = and i32 %a, 2
@@ -160,9 +345,21 @@ define i1 @test10(i32 %a) {
   ret i1 %or.cond
 }
 
+define i1 @test10_logical(i32 %a) {
+; CHECK-LABEL: @test10_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[A:%.*]], 2
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %1 = and i32 %a, 2
+  %2 = icmp eq i32 %1, 0
+  %3 = icmp ult i32 %a, 4
+  %or.cond = select i1 %2, i1 %3, i1 false
+  ret i1 %or.cond
+}
+
 define i1 @test11(i32 %a) {
 ; CHECK-LABEL: @test11(
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 %a, 1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[A:%.*]], 1
 ; CHECK-NEXT:    ret i1 [[TMP1]]
 ;
   %1 = and i32 %a, 2
@@ -171,3 +368,15 @@ define i1 @test11(i32 %a) {
   %or.cond = or i1 %2, %3
   ret i1 %or.cond
 }
+
+define i1 @test11_logical(i32 %a) {
+; CHECK-LABEL: @test11_logical(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[A:%.*]], 1
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %1 = and i32 %a, 2
+  %2 = icmp ne i32 %1, 0
+  %3 = icmp ugt i32 %a, 3
+  %or.cond = select i1 %2, i1 true, i1 %3
+  ret i1 %or.cond
+}

diff  --git a/llvm/test/Transforms/InstCombine/signed-truncation-check.ll b/llvm/test/Transforms/InstCombine/signed-truncation-check.ll
index a69129cbcd22..62a62b97e90d 100644
--- a/llvm/test/Transforms/InstCombine/signed-truncation-check.ll
+++ b/llvm/test/Transforms/InstCombine/signed-truncation-check.ll
@@ -48,6 +48,18 @@ define i1 @positive_with_signbit(i32 %arg) {
   ret i1 %t4
 }
 
+define i1 @positive_with_signbit_logical(i32 %arg) {
+; CHECK-LABEL: @positive_with_signbit_logical(
+; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
+; CHECK-NEXT:    ret i1 [[T4_SIMPLIFIED]]
+;
+  %t1 = icmp sgt i32 %arg, -1
+  %t2 = add i32 %arg, 128
+  %t3 = icmp ult i32 %t2, 256
+  %t4 = select i1 %t1, i1 %t3, i1 false
+  ret i1 %t4
+}
+
 define i1 @positive_with_mask(i32 %arg) {
 ; CHECK-LABEL: @positive_with_mask(
 ; CHECK-NEXT:    [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
@@ -61,6 +73,19 @@ define i1 @positive_with_mask(i32 %arg) {
   ret i1 %t5
 }
 
+define i1 @positive_with_mask_logical(i32 %arg) {
+; CHECK-LABEL: @positive_with_mask_logical(
+; CHECK-NEXT:    [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
+; CHECK-NEXT:    ret i1 [[T5_SIMPLIFIED]]
+;
+  %t1 = and i32 %arg, 1107296256
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = add i32 %arg, 128
+  %t4 = icmp ult i32 %t3, 256
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 define i1 @positive_with_icmp(i32 %arg) {
 ; CHECK-LABEL: @positive_with_icmp(
 ; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
@@ -73,6 +98,18 @@ define i1 @positive_with_icmp(i32 %arg) {
   ret i1 %t4
 }
 
+define i1 @positive_with_icmp_logical(i32 %arg) {
+; CHECK-LABEL: @positive_with_icmp_logical(
+; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
+; CHECK-NEXT:    ret i1 [[T4_SIMPLIFIED]]
+;
+  %t1 = icmp ult i32 %arg, 512
+  %t2 = add i32 %arg, 128
+  %t3 = icmp ult i32 %t2, 256
+  %t4 = select i1 %t1, i1 %t3, i1 false
+  ret i1 %t4
+}
+
 ; Still the same
 define i1 @positive_with_aggressive_icmp(i32 %arg) {
 ; CHECK-LABEL: @positive_with_aggressive_icmp(
@@ -86,6 +123,18 @@ define i1 @positive_with_aggressive_icmp(i32 %arg) {
   ret i1 %t4
 }
 
+define i1 @positive_with_aggressive_icmp_logical(i32 %arg) {
+; CHECK-LABEL: @positive_with_aggressive_icmp_logical(
+; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
+; CHECK-NEXT:    ret i1 [[T4_SIMPLIFIED]]
+;
+  %t1 = icmp ult i32 %arg, 128
+  %t2 = add i32 %arg, 256
+  %t3 = icmp ult i32 %t2, 512
+  %t4 = select i1 %t1, i1 %t3, i1 false
+  ret i1 %t4
+}
+
 ; I'm sure there is a bunch more patterns possible :/
 
 ; This used to trigger an assert, because the icmp's are not direct
@@ -104,6 +153,20 @@ define i1 @positive_with_extra_and(i32 %arg, i1 %z) {
   ret i1 %t5
 }
 
+define i1 @positive_with_extra_and_logical(i32 %arg, i1 %z) {
+; CHECK-LABEL: @positive_with_extra_and_logical(
+; CHECK-NEXT:    [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
+; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[T5_SIMPLIFIED]], [[Z:%.*]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+;
+  %t1 = icmp sgt i32 %arg, -1
+  %t2 = add i32 %arg, 128
+  %t3 = icmp ult i32 %t2, 256
+  %t4 = select i1 %t1, i1 %z, i1 false
+  %t5 = select i1 %t3, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 ; ============================================================================ ;
 ; Vector tests
 ; ============================================================================ ;
@@ -260,6 +323,20 @@ define i1 @commutative() {
   ret i1 %t4
 }
 
+define i1 @commutative_logical() {
+; CHECK-LABEL: @commutative_logical(
+; CHECK-NEXT:    [[ARG:%.*]] = call i32 @gen32()
+; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
+; CHECK-NEXT:    ret i1 [[T4_SIMPLIFIED]]
+;
+  %arg = call i32 @gen32()
+  %t1 = icmp sgt i32 %arg, -1
+  %t2 = add i32 %arg, 128
+  %t3 = icmp ult i32 %t2, 256
+  %t4 = select i1 %t3, i1 %t1, i1 false ; swapped order
+  ret i1 %t4
+}
+
 define i1 @commutative_with_icmp() {
 ; CHECK-LABEL: @commutative_with_icmp(
 ; CHECK-NEXT:    [[ARG:%.*]] = call i32 @gen32()
@@ -274,6 +351,20 @@ define i1 @commutative_with_icmp() {
   ret i1 %t4
 }
 
+define i1 @commutative_with_icmp_logical() {
+; CHECK-LABEL: @commutative_with_icmp_logical(
+; CHECK-NEXT:    [[ARG:%.*]] = call i32 @gen32()
+; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
+; CHECK-NEXT:    ret i1 [[T4_SIMPLIFIED]]
+;
+  %arg = call i32 @gen32()
+  %t1 = icmp ult i32 %arg, 512
+  %t2 = add i32 %arg, 128
+  %t3 = icmp ult i32 %t2, 256
+  %t4 = select i1 %t3, i1 %t1, i1 false ; swapped order
+  ret i1 %t4
+}
+
 ; ============================================================================ ;
 ; Truncations.
 ; ============================================================================ ;
@@ -291,6 +382,19 @@ define i1 @positive_trunc_signbit(i32 %arg) {
   ret i1 %t5
 }
 
+define i1 @positive_trunc_signbit_logical(i32 %arg) {
+; CHECK-LABEL: @positive_trunc_signbit_logical(
+; CHECK-NEXT:    [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG:%.*]], 128
+; CHECK-NEXT:    ret i1 [[T5_SIMPLIFIED]]
+;
+  %t1 = trunc i32 %arg to i8
+  %t2 = icmp sgt i8 %t1, -1
+  %t3 = add i32 %arg, 128
+  %t4 = icmp ult i32 %t3, 256
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 define i1 @positive_trunc_base(i32 %arg) {
 ; CHECK-LABEL: @positive_trunc_base(
 ; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i16
@@ -305,6 +409,20 @@ define i1 @positive_trunc_base(i32 %arg) {
   ret i1 %t5
 }
 
+define i1 @positive_trunc_base_logical(i32 %arg) {
+; CHECK-LABEL: @positive_trunc_base_logical(
+; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i16
+; CHECK-NEXT:    [[T5_SIMPLIFIED:%.*]] = icmp ult i16 [[T1]], 128
+; CHECK-NEXT:    ret i1 [[T5_SIMPLIFIED]]
+;
+  %t1 = trunc i32 %arg to i16
+  %t2 = icmp sgt i16 %t1, -1
+  %t3 = add i16 %t1, 128
+  %t4 = icmp ult i16 %t3, 256
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 define i1 @positive_
diff erent_trunc_both(i32 %arg) {
 ; CHECK-LABEL: @positive_
diff erent_trunc_both(
 ; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i15
@@ -324,6 +442,25 @@ define i1 @positive_
diff erent_trunc_both(i32 %arg) {
   ret i1 %t6
 }
 
+define i1 @positive_
diff erent_trunc_both_logical(i32 %arg) {
+; CHECK-LABEL: @positive_
diff erent_trunc_both_logical(
+; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i15
+; CHECK-NEXT:    [[T2:%.*]] = icmp sgt i15 [[T1]], -1
+; CHECK-NEXT:    [[T3:%.*]] = trunc i32 [[ARG]] to i16
+; CHECK-NEXT:    [[T4:%.*]] = add i16 [[T3]], 128
+; CHECK-NEXT:    [[T5:%.*]] = icmp ult i16 [[T4]], 256
+; CHECK-NEXT:    [[T6:%.*]] = and i1 [[T2]], [[T5]]
+; CHECK-NEXT:    ret i1 [[T6]]
+;
+  %t1 = trunc i32 %arg to i15
+  %t2 = icmp sgt i15 %t1, -1
+  %t3 = trunc i32 %arg to i16
+  %t4 = add i16 %t3, 128
+  %t5 = icmp ult i16 %t4, 256
+  %t6 = select i1 %t2, i1 %t5, i1 false
+  ret i1 %t6
+}
+
 ; ============================================================================ ;
 ; One-use tests.
 ;
@@ -357,6 +494,27 @@ define i1 @oneuse_with_signbit(i32 %arg) {
   ret i1 %t4
 }
 
+define i1 @oneuse_with_signbit_logical(i32 %arg) {
+; CHECK-LABEL: @oneuse_with_signbit_logical(
+; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
+; CHECK-NEXT:    call void @use1(i1 [[T1]])
+; CHECK-NEXT:    [[T2:%.*]] = add i32 [[ARG]], 128
+; CHECK-NEXT:    call void @use32(i32 [[T2]])
+; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 256
+; CHECK-NEXT:    call void @use1(i1 [[T3]])
+; CHECK-NEXT:    [[T4_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
+; CHECK-NEXT:    ret i1 [[T4_SIMPLIFIED]]
+;
+  %t1 = icmp sgt i32 %arg, -1
+  call void @use1(i1 %t1)
+  %t2 = add i32 %arg, 128
+  call void @use32(i32 %t2)
+  %t3 = icmp ult i32 %t2, 256
+  call void @use1(i1 %t3)
+  %t4 = select i1 %t1, i1 %t3, i1 false
+  ret i1 %t4
+}
+
 define i1 @oneuse_with_mask(i32 %arg) {
 ; CHECK-LABEL: @oneuse_with_mask(
 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 603979776
@@ -382,6 +540,31 @@ define i1 @oneuse_with_mask(i32 %arg) {
   ret i1 %t5
 }
 
+define i1 @oneuse_with_mask_logical(i32 %arg) {
+; CHECK-LABEL: @oneuse_with_mask_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 603979776
+; CHECK-NEXT:    call void @use32(i32 [[T1]])
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    call void @use1(i1 [[T2]])
+; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG]], 128
+; CHECK-NEXT:    call void @use32(i32 [[T3]])
+; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
+; CHECK-NEXT:    call void @use1(i1 [[T4]])
+; CHECK-NEXT:    [[T5_SIMPLIFIED:%.*]] = icmp ult i32 [[ARG]], 128
+; CHECK-NEXT:    ret i1 [[T5_SIMPLIFIED]]
+;
+  %t1 = and i32 %arg, 603979776 ; some bit within the target 4294967168 mask.
+  call void @use32(i32 %t1)
+  %t2 = icmp eq i32 %t1, 0
+  call void @use1(i1 %t2)
+  %t3 = add i32 %arg, 128
+  call void @use32(i32 %t3)
+  %t4 = icmp ult i32 %t3, 256
+  call void @use1(i1 %t4)
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 define i1 @oneuse_shl_ashr(i32 %arg) {
 ; CHECK-LABEL: @oneuse_shl_ashr(
 ; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
@@ -411,6 +594,35 @@ define i1 @oneuse_shl_ashr(i32 %arg) {
   ret i1 %t6
 }
 
+define i1 @oneuse_shl_ashr_logical(i32 %arg) {
+; CHECK-LABEL: @oneuse_shl_ashr_logical(
+; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
+; CHECK-NEXT:    call void @use8(i8 [[T1]])
+; CHECK-NEXT:    [[T2:%.*]] = icmp sgt i8 [[T1]], -1
+; CHECK-NEXT:    call void @use1(i1 [[T2]])
+; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[ARG]], 24
+; CHECK-NEXT:    call void @use32(i32 [[T3]])
+; CHECK-NEXT:    [[T4:%.*]] = ashr exact i32 [[T3]], 24
+; CHECK-NEXT:    call void @use32(i32 [[T4]])
+; CHECK-NEXT:    [[T5:%.*]] = icmp eq i32 [[T4]], [[ARG]]
+; CHECK-NEXT:    call void @use1(i1 [[T5]])
+; CHECK-NEXT:    [[T6:%.*]] = and i1 [[T2]], [[T5]]
+; CHECK-NEXT:    ret i1 [[T6]]
+;
+  %t1 = trunc i32 %arg to i8
+  call void @use8(i8 %t1)
+  %t2 = icmp sgt i8 %t1, -1
+  call void @use1(i1 %t2)
+  %t3 = shl i32 %arg, 24
+  call void @use32(i32 %t3)
+  %t4 = ashr i32 %t3, 24
+  call void @use32(i32 %t4)
+  %t5 = icmp eq i32 %t4, %arg
+  call void @use1(i1 %t5)
+  %t6 = select i1 %t2, i1 %t5, i1 false
+  ret i1 %t6
+}
+
 define zeroext i1 @oneuse_trunc_sext(i32 %arg) {
 ; CHECK-LABEL: @oneuse_trunc_sext(
 ; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
@@ -440,6 +652,35 @@ define zeroext i1 @oneuse_trunc_sext(i32 %arg) {
   ret i1 %t6
 }
 
+define zeroext i1 @oneuse_trunc_sext_logical(i32 %arg) {
+; CHECK-LABEL: @oneuse_trunc_sext_logical(
+; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
+; CHECK-NEXT:    call void @use8(i8 [[T1]])
+; CHECK-NEXT:    [[T2:%.*]] = icmp sgt i8 [[T1]], -1
+; CHECK-NEXT:    call void @use1(i1 [[T2]])
+; CHECK-NEXT:    [[T3:%.*]] = trunc i32 [[ARG]] to i8
+; CHECK-NEXT:    call void @use8(i8 [[T3]])
+; CHECK-NEXT:    [[T4:%.*]] = sext i8 [[T3]] to i32
+; CHECK-NEXT:    call void @use32(i32 [[T4]])
+; CHECK-NEXT:    [[T5:%.*]] = icmp eq i32 [[T4]], [[ARG]]
+; CHECK-NEXT:    call void @use1(i1 [[T5]])
+; CHECK-NEXT:    [[T6:%.*]] = and i1 [[T2]], [[T5]]
+; CHECK-NEXT:    ret i1 [[T6]]
+;
+  %t1 = trunc i32 %arg to i8
+  call void @use8(i8 %t1)
+  %t2 = icmp sgt i8 %t1, -1
+  call void @use1(i1 %t2)
+  %t3 = trunc i32 %arg to i8
+  call void @use8(i8 %t3)
+  %t4 = sext i8 %t3 to i32
+  call void @use32(i32 %t4)
+  %t5 = icmp eq i32 %t4, %arg
+  call void @use1(i1 %t5)
+  %t6 = select i1 %t2, i1 %t5, i1 false
+  ret i1 %t6
+}
+
 ; ============================================================================ ;
 ; Negative tests
 ; ============================================================================ ;
@@ -459,6 +700,21 @@ define i1 @negative_not_arg(i32 %arg, i32 %arg2) {
   ret i1 %t4
 }
 
+define i1 @negative_not_arg_logical(i32 %arg, i32 %arg2) {
+; CHECK-LABEL: @negative_not_arg_logical(
+; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
+; CHECK-NEXT:    [[T2:%.*]] = add i32 [[ARG2:%.*]], 128
+; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 256
+; CHECK-NEXT:    [[T4:%.*]] = and i1 [[T1]], [[T3]]
+; CHECK-NEXT:    ret i1 [[T4]]
+;
+  %t1 = icmp sgt i32 %arg, -1
+  %t2 = add i32 %arg2, 128 ; not %arg
+  %t3 = icmp ult i32 %t2, 256
+  %t4 = select i1 %t1, i1 %t3, i1 false
+  ret i1 %t4
+}
+
 define i1 @negative_trunc_not_arg(i32 %arg, i32 %arg2) {
 ; CHECK-LABEL: @negative_trunc_not_arg(
 ; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
@@ -476,6 +732,23 @@ define i1 @negative_trunc_not_arg(i32 %arg, i32 %arg2) {
   ret i1 %t5
 }
 
+define i1 @negative_trunc_not_arg_logical(i32 %arg, i32 %arg2) {
+; CHECK-LABEL: @negative_trunc_not_arg_logical(
+; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
+; CHECK-NEXT:    [[T2:%.*]] = icmp sgt i8 [[T1]], -1
+; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG2:%.*]], 128
+; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
+; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = trunc i32 %arg to i8
+  %t2 = icmp sgt i8 %t1, -1
+  %t3 = add i32 %arg2, 128 ; not %arg
+  %t4 = icmp ult i32 %t3, 256
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 define i1 @positive_with_mask_not_arg(i32 %arg, i32 %arg2) {
 ; CHECK-LABEL: @positive_with_mask_not_arg(
 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 1140850688
@@ -493,6 +766,23 @@ define i1 @positive_with_mask_not_arg(i32 %arg, i32 %arg2) {
   ret i1 %t5
 }
 
+define i1 @positive_with_mask_not_arg_logical(i32 %arg, i32 %arg2) {
+; CHECK-LABEL: @positive_with_mask_not_arg_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 1140850688
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG2:%.*]], 128
+; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
+; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %arg, 1140850688
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = add i32 %arg2, 128 ; not %arg
+  %t4 = icmp ult i32 %t3, 256
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 define i1 @negative_with_nonuniform_bad_mask(i32 %arg) {
 ; CHECK-LABEL: @negative_with_nonuniform_bad_mask(
 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 1711276033
@@ -510,6 +800,23 @@ define i1 @negative_with_nonuniform_bad_mask(i32 %arg) {
   ret i1 %t5
 }
 
+define i1 @negative_with_nonuniform_bad_mask_logical(i32 %arg) {
+; CHECK-LABEL: @negative_with_nonuniform_bad_mask_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 1711276033
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG]], 128
+; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
+; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %arg, 1711276033 ; lowest bit is set
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = add i32 %arg, 128
+  %t4 = icmp ult i32 %t3, 256
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 define i1 @negative_with_uniform_bad_mask(i32 %arg) {
 ; CHECK-LABEL: @negative_with_uniform_bad_mask(
 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], -16777152
@@ -527,6 +834,23 @@ define i1 @negative_with_uniform_bad_mask(i32 %arg) {
   ret i1 %t5
 }
 
+define i1 @negative_with_uniform_bad_mask_logical(i32 %arg) {
+; CHECK-LABEL: @negative_with_uniform_bad_mask_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], -16777152
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG]], 128
+; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
+; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %arg, 4278190144 ; 7'th bit is set
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = add i32 %arg, 128
+  %t4 = icmp ult i32 %t3, 256
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 define i1 @negative_with_wrong_mask(i32 %arg) {
 ; CHECK-LABEL: @negative_with_wrong_mask(
 ; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 1
@@ -544,6 +868,23 @@ define i1 @negative_with_wrong_mask(i32 %arg) {
   ret i1 %t5
 }
 
+define i1 @negative_with_wrong_mask_logical(i32 %arg) {
+; CHECK-LABEL: @negative_with_wrong_mask_logical(
+; CHECK-NEXT:    [[T1:%.*]] = and i32 [[ARG:%.*]], 1
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG]], 128
+; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
+; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = and i32 %arg, 1 ; not even checking the right mask
+  %t2 = icmp eq i32 %t1, 0
+  %t3 = add i32 %arg, 128
+  %t4 = icmp ult i32 %t3, 256
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 define i1 @negative_not_less_than(i32 %arg) {
 ; CHECK-LABEL: @negative_not_less_than(
 ; CHECK-NEXT:    ret i1 false
@@ -555,6 +896,17 @@ define i1 @negative_not_less_than(i32 %arg) {
   ret i1 %t4
 }
 
+define i1 @negative_not_less_than_logical(i32 %arg) {
+; CHECK-LABEL: @negative_not_less_than_logical(
+; CHECK-NEXT:    ret i1 false
+;
+  %t1 = icmp sgt i32 %arg, -1
+  %t2 = add i32 %arg, 256 ; should be less than 256
+  %t3 = icmp ult i32 %t2, 256
+  %t4 = select i1 %t1, i1 %t3, i1 false
+  ret i1 %t4
+}
+
 define i1 @negative_not_power_of_two(i32 %arg) {
 ; CHECK-LABEL: @negative_not_power_of_two(
 ; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
@@ -570,6 +922,21 @@ define i1 @negative_not_power_of_two(i32 %arg) {
   ret i1 %t4
 }
 
+define i1 @negative_not_power_of_two_logical(i32 %arg) {
+; CHECK-LABEL: @negative_not_power_of_two_logical(
+; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
+; CHECK-NEXT:    [[T2:%.*]] = add i32 [[ARG]], 255
+; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 256
+; CHECK-NEXT:    [[T4:%.*]] = and i1 [[T1]], [[T3]]
+; CHECK-NEXT:    ret i1 [[T4]]
+;
+  %t1 = icmp sgt i32 %arg, -1
+  %t2 = add i32 %arg, 255 ; should be power of two
+  %t3 = icmp ult i32 %t2, 256
+  %t4 = select i1 %t1, i1 %t3, i1 false
+  ret i1 %t4
+}
+
 define i1 @negative_not_next_power_of_two(i32 %arg) {
 ; CHECK-LABEL: @negative_not_next_power_of_two(
 ; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
@@ -585,6 +952,21 @@ define i1 @negative_not_next_power_of_two(i32 %arg) {
   ret i1 %t4
 }
 
+define i1 @negative_not_next_power_of_two_logical(i32 %arg) {
+; CHECK-LABEL: @negative_not_next_power_of_two_logical(
+; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
+; CHECK-NEXT:    [[T2:%.*]] = add i32 [[ARG]], 64
+; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 256
+; CHECK-NEXT:    [[T4:%.*]] = and i1 [[T1]], [[T3]]
+; CHECK-NEXT:    ret i1 [[T4]]
+;
+  %t1 = icmp sgt i32 %arg, -1
+  %t2 = add i32 %arg, 64 ; should be 256 >> 1
+  %t3 = icmp ult i32 %t2, 256
+  %t4 = select i1 %t1, i1 %t3, i1 false
+  ret i1 %t4
+}
+
 ; I don't think this can be folded, at least not into single instruction.
 define i1 @two_signed_truncation_checks(i32 %arg) {
 ; CHECK-LABEL: @two_signed_truncation_checks(
@@ -603,6 +985,23 @@ define i1 @two_signed_truncation_checks(i32 %arg) {
   ret i1 %t5
 }
 
+define i1 @two_signed_truncation_checks_logical(i32 %arg) {
+; CHECK-LABEL: @two_signed_truncation_checks_logical(
+; CHECK-NEXT:    [[T1:%.*]] = add i32 [[ARG:%.*]], 512
+; CHECK-NEXT:    [[T2:%.*]] = icmp ult i32 [[T1]], 1024
+; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG]], 128
+; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
+; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = add i32 %arg, 512
+  %t2 = icmp ult i32 %t1, 1024
+  %t3 = add i32 %arg, 128
+  %t4 = icmp ult i32 %t3, 256
+  %t5 = select i1 %t2, i1 %t4, i1 false
+  ret i1 %t5
+}
+
 define i1 @bad_trunc_stc(i32 %arg) {
 ; CHECK-LABEL: @bad_trunc_stc(
 ; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
@@ -619,3 +1018,20 @@ define i1 @bad_trunc_stc(i32 %arg) {
   %t5 = and i1 %t1, %t4
   ret i1 %t5
 }
+
+define i1 @bad_trunc_stc_logical(i32 %arg) {
+; CHECK-LABEL: @bad_trunc_stc_logical(
+; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i32 [[ARG:%.*]], -1
+; CHECK-NEXT:    [[T2:%.*]] = trunc i32 [[ARG]] to i16
+; CHECK-NEXT:    [[T3:%.*]] = add i16 [[T2]], 128
+; CHECK-NEXT:    [[T4:%.*]] = icmp ult i16 [[T3]], 256
+; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T1]], [[T4]]
+; CHECK-NEXT:    ret i1 [[T5]]
+;
+  %t1 = icmp sgt i32 %arg, -1 ; checks a bit outside of the i16
+  %t2 = trunc i32 %arg to i16
+  %t3 = add i16 %t2, 128
+  %t4 = icmp ult i16 %t3, 256
+  %t5 = select i1 %t1, i1 %t4, i1 false
+  ret i1 %t5
+}

diff  --git a/llvm/test/Transforms/InstCombine/umul-sign-check.ll b/llvm/test/Transforms/InstCombine/umul-sign-check.ll
index aae1cbe3cd38..8fa659396f2e 100644
--- a/llvm/test/Transforms/InstCombine/umul-sign-check.ll
+++ b/llvm/test/Transforms/InstCombine/umul-sign-check.ll
@@ -30,6 +30,25 @@ define i1 @test1(i64 %a, i64 %b, i64* %ptr) {
   ret i1 %overflow.1
 }
 
+define i1 @test1_logical(i64 %a, i64 %b, i64* %ptr) {
+; CHECK-LABEL: @test1_logical(
+; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[A]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[B]], 0
+; CHECK-NEXT:    [[OVERFLOW_1:%.*]] = and i1 [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    store i64 [[MUL]], i64* [[PTR:%.*]], align 8
+; CHECK-NEXT:    ret i1 [[OVERFLOW_1]]
+;
+
+  %res = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %a, i64 %b)
+  %overflow = extractvalue { i64, i1 } %res, 1
+  %mul = extractvalue { i64, i1 } %res, 0
+  %cmp  = icmp ne i64 %mul, 0
+  %overflow.1 = select i1 %overflow, i1 true, i1 %cmp
+  store i64 %mul, i64* %ptr, align 8
+  ret i1 %overflow.1
+}
+
 define i1 @test1_or_ops_swapped(i64 %a, i64 %b, i64* %ptr) {
 ; CHECK-LABEL: @test1_or_ops_swapped(
 ; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[A:%.*]], [[B:%.*]]
@@ -50,6 +69,26 @@ define i1 @test1_or_ops_swapped(i64 %a, i64 %b, i64* %ptr) {
   ret i1 %overflow.1
 }
 
+define i1 @test1_or_ops_swapped_logical(i64 %a, i64 %b, i64* %ptr) {
+; CHECK-LABEL: @test1_or_ops_swapped_logical(
+; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[A]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[B]], 0
+; CHECK-NEXT:    [[OVERFLOW_1:%.*]] = and i1 [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    store i64 [[MUL]], i64* [[PTR:%.*]], align 8
+; CHECK-NEXT:    ret i1 [[OVERFLOW_1]]
+;
+
+
+  %res = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %a, i64 %b)
+  %overflow = extractvalue { i64, i1 } %res, 1
+  %mul = extractvalue { i64, i1 } %res, 0
+  %cmp  = icmp ne i64 %mul, 0
+  %overflow.1 = select i1 %cmp, i1 true, i1 %overflow
+  store i64 %mul, i64* %ptr, align 8
+  ret i1 %overflow.1
+}
+
 define i1 @test2(i64 %a, i64 %b, i64* %ptr) {
 ; CHECK-LABEL: @test2(
 ; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[A:%.*]], [[B:%.*]]
@@ -71,6 +110,27 @@ define i1 @test2(i64 %a, i64 %b, i64* %ptr) {
   ret i1 %overflow.1
 }
 
+define i1 @test2_logical(i64 %a, i64 %b, i64* %ptr) {
+; CHECK-LABEL: @test2_logical(
+; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[A]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[B]], 0
+; CHECK-NEXT:    [[OVERFLOW_1:%.*]] = and i1 [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    [[NEG:%.*]] = sub i64 0, [[MUL]]
+; CHECK-NEXT:    store i64 [[NEG]], i64* [[PTR:%.*]], align 8
+; CHECK-NEXT:    ret i1 [[OVERFLOW_1]]
+;
+
+  %res = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %a, i64 %b)
+  %overflow = extractvalue { i64, i1 } %res, 1
+  %mul = extractvalue { i64, i1 } %res, 0
+  %cmp = icmp ne i64 %mul, 0
+  %overflow.1 = select i1 %overflow, i1 true, i1 %cmp
+  %neg = sub i64 0, %mul
+  store i64 %neg, i64* %ptr, align 8
+  ret i1 %overflow.1
+}
+
 declare void @use(i1)
 
 define i1 @test3_multiple_overflow_users(i64 %a, i64 %b, i64* %ptr) {
@@ -92,6 +152,25 @@ define i1 @test3_multiple_overflow_users(i64 %a, i64 %b, i64* %ptr) {
   ret i1 %overflow.1
 }
 
+define i1 @test3_multiple_overflow_users_logical(i64 %a, i64 %b, i64* %ptr) {
+; CHECK-LABEL: @test3_multiple_overflow_users_logical(
+; CHECK-NEXT:    [[RES:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]])
+; CHECK-NEXT:    [[OVERFLOW:%.*]] = extractvalue { i64, i1 } [[RES]], 1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[A]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[B]], 0
+; CHECK-NEXT:    [[OVERFLOW_1:%.*]] = and i1 [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    call void @use(i1 [[OVERFLOW]])
+; CHECK-NEXT:    ret i1 [[OVERFLOW_1]]
+;
+  %res = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %a, i64 %b)
+  %overflow = extractvalue { i64, i1 } %res, 1
+  %mul = extractvalue { i64, i1 } %res, 0
+  %cmp = icmp ne i64 %mul, 0
+  %overflow.1 = select i1 %overflow, i1 true, i1 %cmp
+  call void @use(i1 %overflow)
+  ret i1 %overflow.1
+}
+
 ; Do not simplify if %overflow and %mul have multiple uses.
 define i1 @test3_multiple_overflow_and_mul_users(i64 %a, i64 %b, i64* %ptr) {
 ; CHECK-LABEL: @test3_multiple_overflow_and_mul_users(
@@ -116,6 +195,29 @@ define i1 @test3_multiple_overflow_and_mul_users(i64 %a, i64 %b, i64* %ptr) {
   ret i1 %overflow.1
 }
 
+define i1 @test3_multiple_overflow_and_mul_users_logical(i64 %a, i64 %b, i64* %ptr) {
+; CHECK-LABEL: @test3_multiple_overflow_and_mul_users_logical(
+; CHECK-NEXT:    [[RES:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]])
+; CHECK-NEXT:    [[OVERFLOW:%.*]] = extractvalue { i64, i1 } [[RES]], 1
+; CHECK-NEXT:    [[MUL:%.*]] = extractvalue { i64, i1 } [[RES]], 0
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[MUL]], 0
+; CHECK-NEXT:    [[OVERFLOW_1:%.*]] = or i1 [[OVERFLOW]], [[CMP]]
+; CHECK-NEXT:    [[NEG:%.*]] = sub i64 0, [[MUL]]
+; CHECK-NEXT:    store i64 [[NEG]], i64* [[PTR:%.*]], align 8
+; CHECK-NEXT:    call void @use(i1 [[OVERFLOW]])
+; CHECK-NEXT:    ret i1 [[OVERFLOW_1]]
+;
+  %res = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %a, i64 %b)
+  %overflow = extractvalue { i64, i1 } %res, 1
+  %mul = extractvalue { i64, i1 } %res, 0
+  %cmp = icmp ne i64 %mul, 0
+  %overflow.1 = select i1 %overflow, i1 true, i1 %cmp
+  %neg = sub i64 0, %mul
+  store i64 %neg, i64* %ptr, align 8
+  call void @use(i1 %overflow)
+  ret i1 %overflow.1
+}
+
 
 declare void @use.2({ i64, i1 })
 define i1 @test3_multiple_res_users(i64 %a, i64 %b, i64* %ptr) {
@@ -141,6 +243,29 @@ define i1 @test3_multiple_res_users(i64 %a, i64 %b, i64* %ptr) {
   ret i1 %overflow.1
 }
 
+define i1 @test3_multiple_res_users_logical(i64 %a, i64 %b, i64* %ptr) {
+; CHECK-LABEL: @test3_multiple_res_users_logical(
+; CHECK-NEXT:    [[RES:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]])
+; CHECK-NEXT:    [[MUL:%.*]] = extractvalue { i64, i1 } [[RES]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[A]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[B]], 0
+; CHECK-NEXT:    [[OVERFLOW_1:%.*]] = and i1 [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    [[NEG:%.*]] = sub i64 0, [[MUL]]
+; CHECK-NEXT:    store i64 [[NEG]], i64* [[PTR:%.*]], align 8
+; CHECK-NEXT:    call void @use.2({ i64, i1 } [[RES]])
+; CHECK-NEXT:    ret i1 [[OVERFLOW_1]]
+;
+  %res = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %a, i64 %b)
+  %overflow = extractvalue { i64, i1 } %res, 1
+  %mul = extractvalue { i64, i1 } %res, 0
+  %cmp = icmp ne i64 %mul, 0
+  %overflow.1 = select i1 %overflow, i1 true, i1 %cmp
+  %neg = sub i64 0, %mul
+  store i64 %neg, i64* %ptr, align 8
+  call void @use.2({ i64, i1 } %res)
+  ret i1 %overflow.1
+}
+
 declare void @use.3(i64)
 
 ; Simplify if %mul has multiple uses.
@@ -167,6 +292,29 @@ define i1 @test3_multiple_mul_users(i64 %a, i64 %b, i64* %ptr) {
   ret i1 %overflow.1
 }
 
+define i1 @test3_multiple_mul_users_logical(i64 %a, i64 %b, i64* %ptr) {
+; CHECK-LABEL: @test3_multiple_mul_users_logical(
+; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[A]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i64 [[B]], 0
+; CHECK-NEXT:    [[OVERFLOW_1:%.*]] = and i1 [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    [[NEG:%.*]] = sub i64 0, [[MUL]]
+; CHECK-NEXT:    store i64 [[NEG]], i64* [[PTR:%.*]], align 8
+; CHECK-NEXT:    call void @use.3(i64 [[MUL]])
+; CHECK-NEXT:    ret i1 [[OVERFLOW_1]]
+;
+
+  %res = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %a, i64 %b)
+  %overflow = extractvalue { i64, i1 } %res, 1
+  %mul = extractvalue { i64, i1 } %res, 0
+  %cmp = icmp ne i64 %mul, 0
+  %overflow.1 = select i1 %overflow, i1 true, i1 %cmp
+  %neg = sub i64 0, %mul
+  store i64 %neg, i64* %ptr, align 8
+  call void @use.3(i64 %mul)
+  ret i1 %overflow.1
+}
+
 
 
 define i1 @test4_no_icmp_ne(i64 %a, i64 %b, i64* %ptr) {
@@ -190,4 +338,25 @@ define i1 @test4_no_icmp_ne(i64 %a, i64 %b, i64* %ptr) {
   ret i1 %overflow.1
 }
 
+define i1 @test4_no_icmp_ne_logical(i64 %a, i64 %b, i64* %ptr) {
+; CHECK-LABEL: @test4_no_icmp_ne_logical(
+; CHECK-NEXT:    [[RES:%.*]] = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]])
+; CHECK-NEXT:    [[OVERFLOW:%.*]] = extractvalue { i64, i1 } [[RES]], 1
+; CHECK-NEXT:    [[MUL:%.*]] = extractvalue { i64, i1 } [[RES]], 0
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i64 [[MUL]], 0
+; CHECK-NEXT:    [[OVERFLOW_1:%.*]] = or i1 [[OVERFLOW]], [[CMP]]
+; CHECK-NEXT:    [[NEG:%.*]] = sub i64 0, [[MUL]]
+; CHECK-NEXT:    store i64 [[NEG]], i64* [[PTR:%.*]], align 8
+; CHECK-NEXT:    ret i1 [[OVERFLOW_1]]
+;
+  %res = tail call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %a, i64 %b)
+  %overflow = extractvalue { i64, i1 } %res, 1
+  %mul = extractvalue { i64, i1 } %res, 0
+  %cmp = icmp sgt i64 %mul, 0
+  %overflow.1 = select i1 %overflow, i1 true, i1 %cmp
+  %neg = sub i64 0, %mul
+  store i64 %neg, i64* %ptr, align 8
+  ret i1 %overflow.1
+}
+
 attributes #0 = { nounwind readnone speculatable willreturn }

diff  --git a/llvm/test/Transforms/InstCombine/usub-overflow-known-by-implied-cond.ll b/llvm/test/Transforms/InstCombine/usub-overflow-known-by-implied-cond.ll
index c51ce4fdce5f..abe6e682761f 100644
--- a/llvm/test/Transforms/InstCombine/usub-overflow-known-by-implied-cond.ll
+++ b/llvm/test/Transforms/InstCombine/usub-overflow-known-by-implied-cond.ll
@@ -6,8 +6,8 @@ declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
 
 define i32 @test1(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test1(
-; CHECK-NEXT:    [[COND:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT:    br i1 [[COND]], label [[BB3:%.*]], label [[BB1:%.*]]
+; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    br i1 [[COND_NOT]], label [[BB3:%.*]], label [[BB1:%.*]]
 ; CHECK:       bb1:
 ; CHECK-NEXT:    br i1 false, label [[BB2:%.*]], label [[BB3]]
 ; CHECK:       bb2:
@@ -33,8 +33,8 @@ bb3:
 
 define i32 @test2(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test2(
-; CHECK-NEXT:    [[COND:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT:    br i1 [[COND]], label [[BB3:%.*]], label [[BB1:%.*]]
+; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    br i1 [[COND_NOT]], label [[BB3:%.*]], label [[BB1:%.*]]
 ; CHECK:       bb1:
 ; CHECK-NEXT:    br i1 false, label [[BB3]], label [[BB2:%.*]]
 ; CHECK:       bb2:
@@ -203,8 +203,8 @@ bb3:
 
 define i32 @test8(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test8(
-; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT:    br i1 [[COND]], label [[BB3:%.*]], label [[BB1:%.*]]
+; CHECK-NEXT:    [[COND_NOT:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    br i1 [[COND_NOT]], label [[BB3:%.*]], label [[BB1:%.*]]
 ; CHECK:       bb1:
 ; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
 ; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
@@ -261,6 +261,36 @@ bb3:
   ret i32 0
 }
 
+define i32 @test9_logical(i32 %a, i32 %b, i1 %cond2) {
+; CHECK-LABEL: @test9_logical(
+; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[COND]], [[COND2:%.*]]
+; CHECK-NEXT:    br i1 [[AND]], label [[BB1:%.*]], label [[BB3:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    br i1 false, label [[BB3]], label [[BB2:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]]
+; CHECK-NEXT:    ret i32 [[SUB1]]
+; CHECK:       bb3:
+; CHECK-NEXT:    ret i32 0
+;
+  %cond = icmp ugt i32 %a, %b
+  %and = select i1 %cond, i1 %cond2, i1 false
+  br i1 %and, label %bb1, label %bb3
+
+bb1:
+  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
+  %r1 = extractvalue { i32, i1 } %sub1, 0
+  %c1 = extractvalue { i32, i1 } %sub1, 1
+  br i1 %c1, label %bb3, label %bb2
+
+bb2:
+  ret i32 %r1
+
+bb3:
+  ret i32 0
+}
+
 define i32 @test10(i32 %a, i32 %b, i1 %cond2) {
 ; CHECK-LABEL: @test10(
 ; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
@@ -293,6 +323,38 @@ bb3:
   ret i32 0
 }
 
+define i32 @test10_logical(i32 %a, i32 %b, i1 %cond2) {
+; CHECK-LABEL: @test10_logical(
+; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[COND]], [[COND2:%.*]]
+; CHECK-NEXT:    br i1 [[AND]], label [[BB3:%.*]], label [[BB1:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
+; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
+; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
+; CHECK-NEXT:    ret i32 [[R1]]
+; CHECK:       bb3:
+; CHECK-NEXT:    ret i32 0
+;
+  %cond = icmp ugt i32 %a, %b
+  %and = select i1 %cond, i1 %cond2, i1 false
+  br i1 %and, label %bb3, label %bb1
+
+bb1:
+  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
+  %r1 = extractvalue { i32, i1 } %sub1, 0
+  %c1 = extractvalue { i32, i1 } %sub1, 1
+  br i1 %c1, label %bb3, label %bb2
+
+bb2:
+  ret i32 %r1
+
+bb3:
+  ret i32 0
+}
+
 define i32 @test11(i32 %a, i32 %b, i1 %cond2) {
 ; CHECK-LABEL: @test11(
 ; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
@@ -325,6 +387,38 @@ bb3:
   ret i32 0
 }
 
+define i32 @test11_logical(i32 %a, i32 %b, i1 %cond2) {
+; CHECK-LABEL: @test11_logical(
+; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[COND]], [[COND2:%.*]]
+; CHECK-NEXT:    br i1 [[OR]], label [[BB1:%.*]], label [[BB3:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
+; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
+; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
+; CHECK-NEXT:    ret i32 [[R1]]
+; CHECK:       bb3:
+; CHECK-NEXT:    ret i32 0
+;
+  %cond = icmp ugt i32 %a, %b
+  %or = select i1 %cond, i1 true, i1 %cond2
+  br i1 %or, label %bb1, label %bb3
+
+bb1:
+  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
+  %r1 = extractvalue { i32, i1 } %sub1, 0
+  %c1 = extractvalue { i32, i1 } %sub1, 1
+  br i1 %c1, label %bb3, label %bb2
+
+bb2:
+  ret i32 %r1
+
+bb3:
+  ret i32 0
+}
+
 define i32 @test12(i32 %a, i32 %b, i1 %cond2) {
 ; CHECK-LABEL: @test12(
 ; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
@@ -356,3 +450,35 @@ bb2:
 bb3:
   ret i32 0
 }
+
+define i32 @test12_logical(i32 %a, i32 %b, i1 %cond2) {
+; CHECK-LABEL: @test12_logical(
+; CHECK-NEXT:    [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[COND]], [[COND2:%.*]]
+; CHECK-NEXT:    br i1 [[OR]], label [[BB3:%.*]], label [[BB1:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]])
+; CHECK-NEXT:    [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1
+; CHECK-NEXT:    br i1 [[C1]], label [[BB3]], label [[BB2:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0
+; CHECK-NEXT:    ret i32 [[R1]]
+; CHECK:       bb3:
+; CHECK-NEXT:    ret i32 0
+;
+  %cond = icmp ugt i32 %a, %b
+  %or = select i1 %cond, i1 true, i1 %cond2
+  br i1 %or, label %bb3, label %bb1
+
+bb1:
+  %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b)
+  %r1 = extractvalue { i32, i1 } %sub1, 0
+  %c1 = extractvalue { i32, i1 } %sub1, 1
+  br i1 %c1, label %bb3, label %bb2
+
+bb2:
+  ret i32 %r1
+
+bb3:
+  ret i32 0
+}

diff  --git a/llvm/test/Transforms/InstCombine/widenable-conditions.ll b/llvm/test/Transforms/InstCombine/widenable-conditions.ll
index 4f36647241f8..31aa98ff998b 100644
--- a/llvm/test/Transforms/InstCombine/widenable-conditions.ll
+++ b/llvm/test/Transforms/InstCombine/widenable-conditions.ll
@@ -17,6 +17,19 @@ define i1 @test1(i1 %a, i1 %b) {
   ret i1 %and
 }
 
+define i1 @test1_logical(i1 %a, i1 %b) {
+; CHECK-LABEL: @test1_logical(
+; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT:    [[LHS:%.*]] = and i1 [[WC]], [[B:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[LHS]], [[A:%.*]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %wc = call i1 @llvm.experimental.widenable.condition()
+  %lhs = select i1 %b, i1 %wc, i1 false
+  %and = select i1 %lhs, i1 %a, i1 false
+  ret i1 %and
+}
+
 ; Negative test - profitability of dropping WC from first use unclear
 define i1 @test1b(i1 %a, i1 %b) {
 ; CHECK-LABEL: @test1b(
@@ -33,6 +46,21 @@ define i1 @test1b(i1 %a, i1 %b) {
   ret i1 %and
 }
 
+define i1 @test1b_logical(i1 %a, i1 %b) {
+; CHECK-LABEL: @test1b_logical(
+; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT:    [[LHS:%.*]] = and i1 [[WC]], [[B:%.*]]
+; CHECK-NEXT:    call void @use(i1 [[LHS]])
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[LHS]], [[A:%.*]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %wc = call i1 @llvm.experimental.widenable.condition()
+  %lhs = select i1 %b, i1 %wc, i1 false
+  call void @use(i1 %lhs)
+  %and = select i1 %lhs, i1 %a, i1 false
+  ret i1 %and
+}
+
 ; multiple uses of A, B, WC doesn't change result
 define i1 @test1c(i1 %a, i1 %b) {
 ; CHECK-LABEL: @test1c(
@@ -53,6 +81,25 @@ define i1 @test1c(i1 %a, i1 %b) {
   ret i1 %and
 }
 
+define i1 @test1c_logical(i1 %a, i1 %b) {
+; CHECK-LABEL: @test1c_logical(
+; CHECK-NEXT:    call void @use(i1 [[A:%.*]])
+; CHECK-NEXT:    call void @use(i1 [[B:%.*]])
+; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT:    call void @use(i1 [[WC]])
+; CHECK-NEXT:    [[LHS:%.*]] = and i1 [[WC]], [[B]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[LHS]], [[A]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  call void @use(i1 %a)
+  call void @use(i1 %b)
+  %wc = call i1 @llvm.experimental.widenable.condition()
+  call void @use(i1 %wc)
+  %lhs = select i1 %b, i1 %wc, i1 false
+  %and = select i1 %lhs, i1 %a, i1 false
+  ret i1 %and
+}
+
 define i1 @test2(i1 %a, i1 %b) {
 ; CHECK-LABEL: @test2(
 ; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
@@ -66,6 +113,19 @@ define i1 @test2(i1 %a, i1 %b) {
   ret i1 %and
 }
 
+define i1 @test2_logical(i1 %a, i1 %b) {
+; CHECK-LABEL: @test2_logical(
+; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT:    [[LHS:%.*]] = and i1 [[WC]], [[B:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[LHS]], [[A:%.*]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %wc = call i1 @llvm.experimental.widenable.condition()
+  %lhs = select i1 %wc, i1 %b, i1 false
+  %and = select i1 %lhs, i1 %a, i1 false
+  ret i1 %and
+}
+
 ; To test the rhs side, an instruction on lhs to prevent complexity
 ; canonicalization reducing to above.
 define i1 @test3(i1 %a, i1 %b, i1 %c) {
@@ -83,6 +143,21 @@ define i1 @test3(i1 %a, i1 %b, i1 %c) {
   ret i1 %and
 }
 
+define i1 @test3_logical(i1 %a, i1 %b, i1 %c) {
+; CHECK-LABEL: @test3_logical(
+; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT:    [[LHS:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[RHS:%.*]] = and i1 [[WC]], [[C:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[LHS]], [[RHS]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %wc = call i1 @llvm.experimental.widenable.condition()
+  %lhs = select i1 %a, i1 %b, i1 false
+  %rhs = select i1 %c, i1 %wc, i1 false
+  %and = select i1 %lhs, i1 %rhs, i1 false
+  ret i1 %and
+}
+
 define i1 @test4(i1 %a, i1 %b, i1 %c) {
 ; CHECK-LABEL: @test4(
 ; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
@@ -98,6 +173,21 @@ define i1 @test4(i1 %a, i1 %b, i1 %c) {
   ret i1 %and
 }
 
+define i1 @test4_logical(i1 %a, i1 %b, i1 %c) {
+; CHECK-LABEL: @test4_logical(
+; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT:    [[LHS:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT:    [[RHS:%.*]] = and i1 [[WC]], [[C:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[LHS]], [[RHS]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %wc = call i1 @llvm.experimental.widenable.condition()
+  %lhs = select i1 %a, i1 %b, i1 false
+  %rhs = select i1 %wc, i1 %c, i1 false
+  %and = select i1 %lhs, i1 %rhs, i1 false
+  ret i1 %and
+}
+
 define i1 @test5(i1 %a, i1 %b) {
 ; CHECK-LABEL: @test5(
 ; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
@@ -108,6 +198,16 @@ define i1 @test5(i1 %a, i1 %b) {
   ret i1 %and
 }
 
+define i1 @test5_logical(i1 %a, i1 %b) {
+; CHECK-LABEL: @test5_logical(
+; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT:    ret i1 [[WC]]
+;
+  %wc = call i1 @llvm.experimental.widenable.condition()
+  %and = select i1 %wc, i1 %wc, i1 false
+  ret i1 %and
+}
+
 define i1 @test6(i1 %a, i1 %b) {
 ; CHECK-LABEL: @test6(
 ; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
@@ -121,6 +221,19 @@ define i1 @test6(i1 %a, i1 %b) {
   ret i1 %and
 }
 
+define i1 @test6_logical(i1 %a, i1 %b) {
+; CHECK-LABEL: @test6_logical(
+; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT:    [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[WC]], [[WC2]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %wc = call i1 @llvm.experimental.widenable.condition()
+  %wc2 = call i1 @llvm.experimental.widenable.condition()
+  %and = select i1 %wc, i1 %wc2, i1 false
+  ret i1 %and
+}
+
 define i1 @test7(i1 %a, i1 %b) {
 ; CHECK-LABEL: @test7(
 ; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
@@ -136,6 +249,21 @@ define i1 @test7(i1 %a, i1 %b) {
   ret i1 %and
 }
 
+define i1 @test7_logical(i1 %a, i1 %b) {
+; CHECK-LABEL: @test7_logical(
+; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT:    call void @use(i1 [[WC]])
+; CHECK-NEXT:    [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[WC]], [[WC2]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %wc = call i1 @llvm.experimental.widenable.condition()
+  call void @use(i1 %wc)
+  %wc2 = call i1 @llvm.experimental.widenable.condition()
+  %and = select i1 %wc, i1 %wc2, i1 false
+  ret i1 %and
+}
+
 define i1 @test8(i1 %a, i1 %b) {
 ; CHECK-LABEL: @test8(
 ; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
@@ -151,6 +279,21 @@ define i1 @test8(i1 %a, i1 %b) {
   ret i1 %and
 }
 
+define i1 @test8_logical(i1 %a, i1 %b) {
+; CHECK-LABEL: @test8_logical(
+; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT:    [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT:    call void @use(i1 [[WC2]])
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[WC]], [[WC2]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+  %wc = call i1 @llvm.experimental.widenable.condition()
+  %wc2 = call i1 @llvm.experimental.widenable.condition()
+  call void @use(i1 %wc2)
+  %and = select i1 %wc, i1 %wc2, i1 false
+  ret i1 %and
+}
+
 
 declare void @use(i1)
 declare i1 @llvm.experimental.widenable.condition()

diff  --git a/llvm/test/Transforms/InstCombine/zext-or-icmp.ll b/llvm/test/Transforms/InstCombine/zext-or-icmp.ll
index 8223479c8134..a77aa7ac7ebd 100644
--- a/llvm/test/Transforms/InstCombine/zext-or-icmp.ll
+++ b/llvm/test/Transforms/InstCombine/zext-or-icmp.ll
@@ -20,6 +20,23 @@ define i8 @zext_or_icmp_icmp(i8 %a, i8 %b) {
   ret i8 %zext
 }
 
+define i8 @zext_or_icmp_icmp_logical(i8 %a, i8 %b) {
+; CHECK-LABEL: @zext_or_icmp_icmp_logical(
+; CHECK-NEXT:    [[MASK:%.*]] = and i8 [[A:%.*]], 1
+; CHECK-NEXT:    [[TOBOOL2:%.*]] = icmp eq i8 [[B:%.*]], 0
+; CHECK-NEXT:    [[TOBOOL22:%.*]] = zext i1 [[TOBOOL2]] to i8
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[MASK]], 1
+; CHECK-NEXT:    [[ZEXT3:%.*]] = or i8 [[TMP1]], [[TOBOOL22]]
+; CHECK-NEXT:    ret i8 [[ZEXT3]]
+;
+  %mask = and i8 %a, 1
+  %toBool1 = icmp eq i8 %mask, 0
+  %toBool2 = icmp eq i8 %b, 0
+  %bothCond = select i1 %toBool1, i1 true, i1 %toBool2
+  %zext = zext i1 %bothCond to i8
+  ret i8 %zext
+}
+
 ; Here, widening the or from i1 to i32 and removing one of the icmps would
 ; widen an undef value (created by the out-of-range shift), increasing the
 ; range of valid values for the return, so we can't do it.
@@ -56,3 +73,36 @@ block2:
   %conv2 = zext i1 %cmp1 to i32
   ret i32 %conv2
 }
+
+define i32 @dont_widen_undef_logical() {
+; CHECK-LABEL: @dont_widen_undef_logical(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[BLOCK2:%.*]]
+; CHECK:       block1:
+; CHECK-NEXT:    br label [[BLOCK2]]
+; CHECK:       block2:
+; CHECK-NEXT:    [[CMP_I:%.*]] = phi i1 [ false, [[BLOCK1:%.*]] ], [ true, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[M_011:%.*]] = phi i32 [ 0, [[BLOCK1]] ], [ 33, [[ENTRY]] ]
+; CHECK-NEXT:    [[M_1_OP:%.*]] = lshr i32 1, [[M_011]]
+; CHECK-NEXT:    [[SEXT_MASK:%.*]] = and i32 [[M_1_OP]], 65535
+; CHECK-NEXT:    [[CMP115:%.*]] = icmp ne i32 [[SEXT_MASK]], 0
+; CHECK-NEXT:    [[CMP1:%.*]] = or i1 [[CMP_I]], [[CMP115]]
+; CHECK-NEXT:    [[CONV2:%.*]] = zext i1 [[CMP1]] to i32
+; CHECK-NEXT:    ret i32 [[CONV2]]
+;
+entry:
+  br label %block2
+
+block1:
+  br label %block2
+
+block2:
+  %m.011 = phi i32 [ 33, %entry ], [ 0, %block1 ]
+  %cmp.i = icmp ugt i32 %m.011, 1
+  %m.1.op = lshr i32 1, %m.011
+  %sext.mask = and i32 %m.1.op, 65535
+  %cmp115 = icmp ne i32 %sext.mask, 0
+  %cmp1 = select i1 %cmp.i, i1 true, i1 %cmp115
+  %conv2 = zext i1 %cmp1 to i32
+  ret i32 %conv2
+}


        


More information about the llvm-branch-commits mailing list