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 38f6523bec397f..3d08ae5e4012a7 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 ; [#uses=1] + %tmp16 = load i32, i32* %tmp15 ; [#uses=4] + %tmp18 = icmp slt i32 %tmp16, -31 ; [#uses=1] + %tmp21 = icmp sgt i32 %tmp16, 31 ; [#uses=1] + %bothcond = select i1 %tmp18, i1 true, i1 %tmp21 ; [#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 6db886b25ede40..7cedb1c5ced23e 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 fb9b9a6cb5af73..f019507082b3bd 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 ; [#uses=1] + %tmp11.not = icmp sgt i32 %tmp9, 255 ; [#uses=1] + %bothcond = select i1 %tmp20, i1 true, i1 %tmp11.not ; [#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 f872b6a98e096b..8efa821d7de024 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 eb3329b4dd02bf..6dde4402e1fb60 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 ; [#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 7b08a7b3a02577..50657d744da1d8 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 ; [#uses=1] + %tmp71 = fcmp uno float %x, 0.000000e+00 ; [#uses=1] + %bothcond = select i1 %tmp67, i1 true, i1 %tmp71 ; [#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 11226bcf41855b..2b0f364ee375b4 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 9efc35fb2d20ba..bec055a2ee7cf1 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 97956bc2e24975..85792304c50d96 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 8ef65a27c1f55e..d180560bfbcc3a 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 dd51c6548eea64..18689c969bd04d 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 differently 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 7f07147b14ffca..e24bb581230273 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 be573281eb8c02..b8a43c57bf5800 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 a62790bd57f4b7..0e8f0ca7bf9676 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 differ 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 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:%.*]], @@ -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 020dbc483d9de5..669cba88fabaa5 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 47b0d2d6245e4e..6b12e26ab5f377 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 a988eea894450e..f46ffbec2ce669 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 1ecd305e807d90..28464c41ad499e 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 0156c9071a64a9..593e50abdb120e 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 465621a24a54c4..809c43d1a09dfb 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 bc7ddacbed16c9..98d91c9b048f51 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 fc0c13a5f1a7a2..db3e7f3afb967f 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 1a1ec2e2024d10..2546ec387003f2 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 09a3b2b5ff4f7c..6e76525bad3503 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 b5327df5e8e3d9..cc23b114bd01b9 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 b21077e2e2efcb..b48466e678d8c6 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:%.*]], @@ -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 f0d4a80ccfb04b..c54c6271ec07d5 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 2f448ce1c740fe..f67cb024c2e32e 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 2f532be03fbfc3..5c16fc446cdda7 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 6a65b5befa38f5..e9f9bb31a0e4f1 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 7e469bd2528275..f1d0392c1845c2 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 d98361f1b5f615..bc0047e7a84a51 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:%.*]], @@ -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> , [[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:%.*]], @@ -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> , [[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> , [[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> , [[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 10ac51ae32bc3f..da12ddf668c4ff 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 b5da1734c10200..ff624452656326 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:%.*]], @@ -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:%.*]], @@ -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:%.*]], @@ -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:%.*]], @@ -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 ab37c7d56232e4..17d1dd28e1269c 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 ba77beae0f6864..5d56e0a90360c6 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 2b4686004abc2d..bcc62dc983c689 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 7b29bcdd253154..e2f256140b5195 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 ae70b9259f0b96..b875396a8c6dde 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 4a366aa8fb834c..aa018db5076c41 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 c534acd70cdb62..64b16905fb9732 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 272d4a47ce6887..e230b3b9277749 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 819ac6dd3a82de..d603de371ba020 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 @test8vvec( %C, %X) { ; CHECK-LABEL: @test8vvec( -; CHECK-NEXT: [[R:%.*]] = and [[C:%.*]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = and [[C:%.*]], [[X:%.*]] ; CHECK-NEXT: ret [[R]] ; %R = select %C, %X, 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 @bitcast_select_bitcast( %icmp, %a, %b) { ; CHECK-LABEL: @bitcast_select_bitcast( -; CHECK-NEXT: [[BC1:%.*]] = bitcast [[A:%.*]] to -; CHECK-NEXT: [[SELECT:%.*]] = select [[ICMP:%.*]], [[B:%.*]], [[BC1]] -; CHECK-NEXT: ret [[SELECT]] +; CHECK-NEXT: [[TMP1:%.*]] = bitcast [[A:%.*]] to +; CHECK-NEXT: [[BC2:%.*]] = select [[ICMP:%.*]], [[B:%.*]], [[TMP1]] +; CHECK-NEXT: ret [[BC2]] ; %bc1 = bitcast %b to %select = select %icmp, %bc1, %a diff --git a/llvm/test/Transforms/InstCombine/set.ll b/llvm/test/Transforms/InstCombine/set.ll index b8c349aaf94e48..bc2cdb7c469e9a 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:%.*]], -; CHECK-NEXT: ret <2 x i32> [[B]] +; CHECK-NEXT: [[D:%.*]] = and <2 x i32> [[A:%.*]], +; CHECK-NEXT: ret <2 x i32> [[D]] ; %B = and <2 x i32> %A, %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:%.*]], -; CHECK-NEXT: [[TMP_1_LOBIT:%.*]] = and <2 x i32> [[TMP_1]], -; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[TMP_1_LOBIT]], -; CHECK-NEXT: ret <2 x i32> [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[A:%.*]], +; CHECK-NEXT: [[DOTLOBIT:%.*]] = and <2 x i32> [[TMP1]], +; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i32> [[DOTLOBIT]], +; CHECK-NEXT: ret <2 x i32> [[TMP2]] ; %tmp1 = and <2 x i32> %a, %tmp.1 = lshr <2 x i32> %tmp1, diff --git a/llvm/test/Transforms/InstCombine/sign-test-and-or.ll b/llvm/test/Transforms/InstCombine/sign-test-and-or.ll index 1920a800ef1f08..a71cb54b9fc29d 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 a69129cbcd22db..62a62b97e90d25 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_different_trunc_both(i32 %arg) { ; CHECK-LABEL: @positive_different_trunc_both( ; CHECK-NEXT: [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i15 @@ -324,6 +442,25 @@ define i1 @positive_different_trunc_both(i32 %arg) { ret i1 %t6 } +define i1 @positive_different_trunc_both_logical(i32 %arg) { +; CHECK-LABEL: @positive_different_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 aae1cbe3cd38b8..8fa659396f2e1f 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 c51ce4fdce5f64..abe6e682761fc0 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 4f36647241f884..31aa98ff998b09 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 8223479c81348a..a77aa7ac7ebd81 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 +}