[InstCombine] add/move tests for and/or-of-icmps equality folds; NFC

llvm-svn: 300357
This commit is contained in:
Sanjay Patel 2017-04-14 18:19:27 +00:00
parent ffb997a8eb
commit 9d39a9d860
4 changed files with 139 additions and 111 deletions

View File

@ -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 <u 2
define i1 @or_eq_with_diff_one(i8 %x) {
; CHECK-LABEL: @or_eq_with_diff_one(
; CHECK-NEXT: [[TMP1:%.*]] = add i8 %x, -13
; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i8 [[TMP1]], 2
; CHECK-NEXT: ret i1 [[TMP2]]
;
%cmp1 = icmp eq i8 %x, 13
%cmp2 = icmp eq i8 %x, 14
%or = or i1 %cmp1, %cmp2
ret i1 %or
}
; (X != 40 | X != 39) -> 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
}

View File

@ -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

View File

@ -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

View File

@ -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 <u 2
define i1 @cmp_eq_with_diff_one(i8 %x) {
; CHECK-LABEL: @cmp_eq_with_diff_one(
; CHECK-NEXT: [[X_OFF:%.*]] = add i8 %x, -13
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[X_OFF]], 2
; CHECK-NEXT: ret i1 [[TMP1]]
;
%cmp1 = icmp eq i8 %x, 13
%cmp2 = icmp eq i8 %x, 14
%or = or i1 %cmp1, %cmp2
ret i1 %or
}
; Make sure the constants are treated as signed when comparing them.
; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524
define i1 @cmp_eq_with_diff_one_signed(i32 %x) {
; CHECK-LABEL: @cmp_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, -1
%cmp2 = icmp eq i32 %x, 0
%or = or i1 %cmp1, %cmp2
ret i1 %or
}
define i32 @test20(i32 %x) {
; CHECK-LABEL: @test20(
; CHECK-NEXT: ret i32 %x