diff --git a/test/Transforms/InstCombine/and-or-icmps.ll b/test/Transforms/InstCombine/and-or-icmps.ll index 3903472e911..eed407ff261 100644 --- a/test/Transforms/InstCombine/and-or-icmps.ll +++ b/test/Transforms/InstCombine/and-or-icmps.ll @@ -39,15 +39,145 @@ define i1 @PR2330(i32 %a, i32 %b) { ret i1 %and } -define i1 @test(i32 %tmp1030) { -; CHECK-LABEL: @test( -; CHECK-NEXT: [[TMP1030_OFF:%.*]] = add i32 %tmp1030, -39 -; CHECK-NEXT: [[TMP1030_CMP:%.*]] = icmp ugt i32 [[TMP1030_OFF]], 1 -; CHECK-NEXT: ret i1 [[TMP1030_CMP]] +; if LHSC and RHSC differ only by one bit: +; (X == C1 || X == C2) -> (X | (C1 ^ C2)) == C2 +; PR14708: https://bugs.llvm.org/show_bug.cgi?id=14708 + +define i1 @or_eq_with_one_bit_diff_constants1(i32 %x) { +; CHECK-LABEL: @or_eq_with_one_bit_diff_constants1( +; CHECK-NEXT: [[TMP1:%.*]] = or i32 %x, 1 +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 51 +; CHECK-NEXT: ret i1 [[TMP2]] ; - %tmp1037 = icmp ne i32 %tmp1030, 39 - %tmp1039 = icmp ne i32 %tmp1030, 40 - %tmp1042 = and i1 %tmp1037, %tmp1039 - ret i1 %tmp1042 + %cmp1 = icmp eq i32 %x, 50 + %cmp2 = icmp eq i32 %x, 51 + %or = or i1 %cmp1, %cmp2 + ret i1 %or } +; (X != C1 && X != C2) -> (X | (C1 ^ C2)) != C2 + +define i1 @and_ne_with_one_bit_diff_constants1(i32 %x) { +; CHECK-LABEL: @and_ne_with_one_bit_diff_constants1( +; 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 = and i1 %cmp1, %cmp2 + 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) { +; CHECK-LABEL: @or_eq_with_one_bit_diff_constants2( +; CHECK-NEXT: [[TMP1:%.*]] = or i32 %x, 32 +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 97 +; CHECK-NEXT: ret i1 [[TMP2]] +; + %cmp1 = icmp eq i32 %x, 97 + %cmp2 = icmp eq i32 %x, 65 + %or = or i1 %cmp1, %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: [[CMP1:%.*]] = icmp ne i19 %x, 65 +; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i19 %x, 193 +; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] +; CHECK-NEXT: ret i1 [[AND]] +; + %cmp1 = icmp ne i19 %x, 65 + %cmp2 = icmp ne i19 %x, 193 + %and = and i1 %cmp1, %cmp2 + 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) { +; CHECK-LABEL: @or_eq_with_one_bit_diff_constants3( +; CHECK-NEXT: [[TMP1:%.*]] = or i8 %x, -128 +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], -2 +; CHECK-NEXT: ret i1 [[TMP2]] +; + %cmp1 = icmp eq i8 %x, 254 + %cmp2 = icmp eq i8 %x, 126 + %or = or i1 %cmp1, %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: [[CMP1:%.*]] = icmp ne i8 %x, 65 +; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 %x, -63 +; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] +; CHECK-NEXT: ret i1 [[AND]] +; + %cmp1 = icmp ne i8 %x, 65 + %cmp2 = icmp ne i8 %x, 193 + %and = and i1 %cmp1, %cmp2 + 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) { +; CHECK-LABEL: @and_ne_with_diff_one( +; 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 = and i1 %cmp1, %cmp2 + ret i1 %and +} + +; Make sure the constants are treated as signed when comparing them. +; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524 + +define i1 @or_eq_with_diff_one_signed(i32 %x) { +; CHECK-LABEL: @or_eq_with_diff_one_signed( +; 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 = or i1 %cmp1, %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 +; 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 = and i1 %cmp1, %cmp2 + ret i1 %and +} + + + diff --git a/test/Transforms/InstCombine/and.ll b/test/Transforms/InstCombine/and.ll index cc2e0bb7b70..9a4d1e5758b 100644 --- a/test/Transforms/InstCombine/and.ll +++ b/test/Transforms/InstCombine/and.ll @@ -311,19 +311,6 @@ define <2 x i1> @test25vec(<2 x i32> %A) { ret <2 x i1> %D } -define i1 @test26(i32 %A) { -; CHECK-LABEL: @test26( -; CHECK-NEXT: [[A_OFF:%.*]] = add i32 %A, -49 -; CHECK-NEXT: [[A_CMP:%.*]] = icmp ugt i32 [[A_OFF]], 1 -; CHECK-NEXT: ret i1 [[A_CMP]] -; - %B = icmp ne i32 %A, 49 - %C = icmp ne i32 %A, 50 - ;; (A-49) > 1 - %D = and i1 %B, %C - ret i1 %D -} - define i8 @test27(i8 %A) { ; CHECK-LABEL: @test27( ; CHECK-NEXT: ret i8 0 diff --git a/test/Transforms/InstCombine/and2.ll b/test/Transforms/InstCombine/and2.ll index afaddb701a9..001ac58891e 100644 --- a/test/Transforms/InstCombine/and2.ll +++ b/test/Transforms/InstCombine/and2.ll @@ -45,21 +45,6 @@ define <4 x i32> @test5(<4 x i32> %A) { ret <4 x i32> %2 } -; Check that we combine "if x!=0 && x!=-1" into "if x+1u>1" -define i32 @test6(i64 %x) nounwind { -; CHECK-LABEL: @test6( -; CHECK-NEXT: [[X_OFF:%.*]] = add i64 %x, 1 -; CHECK-NEXT: [[X_CMP:%.*]] = icmp ugt i64 [[X_OFF]], 1 -; CHECK-NEXT: [[LAND_EXT:%.*]] = zext i1 [[X_CMP]] to i32 -; CHECK-NEXT: ret i32 [[LAND_EXT]] -; - %cmp1 = icmp ne i64 %x, -1 - %not.cmp = icmp ne i64 %x, 0 - %.cmp1 = and i1 %cmp1, %not.cmp - %land.ext = zext i1 %.cmp1 to i32 - ret i32 %land.ext -} - define i1 @test7(i32 %i, i1 %b) { ; CHECK-LABEL: @test7( ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 %i, 0 diff --git a/test/Transforms/InstCombine/or.ll b/test/Transforms/InstCombine/or.ll index ad46023d8a5..41e6d2d1f82 100644 --- a/test/Transforms/InstCombine/or.ll +++ b/test/Transforms/InstCombine/or.ll @@ -207,80 +207,6 @@ define <2 x i1> @test18vec(<2 x i32> %A) { ret <2 x i1> %D } -; if LHSC and RHSC differ only by one bit: -; (A == C1 || A == C2) -> (A | (C1 ^ C2)) == C2 -; PR14708: https://bugs.llvm.org/show_bug.cgi?id=14708 - -define i1 @cmp_eq_with_one_bit_diff_constants1(i32 %x) { -; CHECK-LABEL: @cmp_eq_with_one_bit_diff_constants1( -; CHECK-NEXT: [[TMP1:%.*]] = or i32 %x, 1 -; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 51 -; CHECK-NEXT: ret i1 [[TMP2]] -; - %cmp1 = icmp eq i32 %x, 50 - %cmp2 = icmp eq i32 %x, 51 - %or = or i1 %cmp1, %cmp2 - ret i1 %or -} - -; The constants are not necessarily off-by-one, just off-by-one-bit. - -define i1 @cmp_eq_with_one_bit_diff_constants2(i32 %x) { -; CHECK-LABEL: @cmp_eq_with_one_bit_diff_constants2( -; CHECK-NEXT: [[TMP1:%.*]] = or i32 %x, 32 -; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 97 -; CHECK-NEXT: ret i1 [[TMP2]] -; - %cmp1 = icmp eq i32 %x, 97 - %cmp2 = icmp eq i32 %x, 65 - %or = or i1 %cmp1, %cmp2 - ret i1 %or -} - -; Make sure the constants are treated as unsigned when comparing them. - -define i1 @cmp_eq_with_one_bit_diff_constants3(i8 %x) { -; CHECK-LABEL: @cmp_eq_with_one_bit_diff_constants3( -; CHECK-NEXT: [[TMP1:%.*]] = or i8 %x, -128 -; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], -2 -; CHECK-NEXT: ret i1 [[TMP2]] -; - %cmp1 = icmp eq i8 %x, 254 - %cmp2 = icmp eq i8 %x, 126 - %or = or i1 %cmp1, %cmp2 - ret i1 %or -} - -; 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