[llvm] 724e2b1 - [InstCombine] Add tests for bitwise (A >> C - 1, zext(icmp)) -> zext (bitwise(A<0, icmp)) fold (NFC)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 24 04:03:35 PDT 2023


Author: XChy
Date: 2023-07-24T13:03:27+02:00
New Revision: 724e2b1225cd7ef7ec1f43dcbe77c9f9f35958d2

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

LOG: [InstCombine] Add tests for bitwise (A >> C - 1, zext(icmp)) -> zext (bitwise(A<0, icmp)) fold (NFC)

Tests for an upcoming bitwise (A >> C - 1, zext(icmp)) ->
zext (bitwise(A<0, icmp)) fold.

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

Added: 
    

Modified: 
    llvm/test/Transforms/InstCombine/and-or-icmps.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/InstCombine/and-or-icmps.ll b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
index 4f5639c2e93d7b..6515d7cb6fbbdf 100644
--- a/llvm/test/Transforms/InstCombine/and-or-icmps.ll
+++ b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
@@ -2682,3 +2682,397 @@ define <2 x i64> @icmp_slt_0_or_icmp_sgt_0_i64x2_fail(<2 x i64> %x) {
   ret <2 x i64> %E
 
 }
+
+define i32 @icmp_slt_0_and_icmp_sge_neg1_i32(i32 %x) {
+; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i32(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -1
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
+; CHECK-NEXT:    [[D:%.*]] = and i32 [[C]], [[B]]
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp sgt i32 %x, -1
+  %B = zext i1 %A to i32
+  %C = lshr i32 %x, 31
+  %D = and i32 %C, %B
+  ret i32 %D
+}
+
+define i32 @icmp_slt_0_or_icmp_sge_neg1_i32(i32 %x) {
+; CHECK-LABEL: @icmp_slt_0_or_icmp_sge_neg1_i32(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -2
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
+; CHECK-NEXT:    [[D:%.*]] = or i32 [[C]], [[B]]
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp sge i32 %x, -1
+  %B = zext i1 %A to i32
+  %C = lshr i32 %x, 31
+  %D = or i32 %C, %B
+  ret i32 %D
+}
+
+define i32 @icmp_slt_0_or_icmp_sge_100_i32(i32 %x) {
+; CHECK-LABEL: @icmp_slt_0_or_icmp_sge_100_i32(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], 99
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
+; CHECK-NEXT:    [[D:%.*]] = or i32 [[C]], [[B]]
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp sge i32 %x, 100
+  %B = zext i1 %A to i32
+  %C = lshr i32 %x, 31
+  %D = or i32 %C, %B
+  ret i32 %D
+}
+
+define i64 @icmp_slt_0_and_icmp_sge_neg1_i64(i64 %x) {
+; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i64(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i64 [[X:%.*]], -2
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i64
+; CHECK-NEXT:    [[C:%.*]] = lshr i64 [[X]], 63
+; CHECK-NEXT:    [[D:%.*]] = and i64 [[C]], [[B]]
+; CHECK-NEXT:    ret i64 [[D]]
+;
+  %A = icmp sge i64 %x, -1
+  %B = zext i1 %A to i64
+  %C = lshr i64 %x, 63
+  %D = and i64 %C, %B
+  ret i64 %D
+}
+
+define i64 @icmp_slt_0_and_icmp_sge_neg2_i64(i64 %x) {
+; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i64(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i64 [[X:%.*]], -3
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i64
+; CHECK-NEXT:    [[C:%.*]] = lshr i64 [[X]], 63
+; CHECK-NEXT:    [[D:%.*]] = and i64 [[C]], [[B]]
+; CHECK-NEXT:    ret i64 [[D]]
+;
+  %A = icmp sge i64 %x, -2
+  %B = zext i1 %A to i64
+  %C = lshr i64 %x, 63
+  %D = and i64 %C, %B
+  ret i64 %D
+}
+
+define i64 @ashr_and_icmp_sge_neg1_i64(i64 %x) {
+; CHECK-LABEL: @ashr_and_icmp_sge_neg1_i64(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i64 [[X:%.*]], -2
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i64
+; CHECK-NEXT:    [[C1:%.*]] = lshr i64 [[X]], 63
+; CHECK-NEXT:    [[D:%.*]] = and i64 [[C1]], [[B]]
+; CHECK-NEXT:    ret i64 [[D]]
+;
+  %A = icmp sge i64 %x, -1
+  %B = zext i1 %A to i64
+  %C = ashr i64 %x, 63
+  %D = and i64 %C, %B
+  ret i64 %D
+}
+
+define i64 @icmp_slt_0_and_icmp_sgt_neg1_i64(i64 %x) {
+; CHECK-LABEL: @icmp_slt_0_and_icmp_sgt_neg1_i64(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i64 [[X:%.*]], -1
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i64
+; CHECK-NEXT:    [[C:%.*]] = lshr i64 [[X]], 63
+; CHECK-NEXT:    [[D:%.*]] = and i64 [[C]], [[B]]
+; CHECK-NEXT:    ret i64 [[D]]
+;
+  %A = icmp sgt i64 %x, -1
+  %B = zext i1 %A to i64
+  %C = lshr i64 %x, 63
+  %D = and i64 %C, %B
+  ret i64 %D
+}
+
+define i64 @icmp_slt_0_and_icmp_sge_neg1_i64_fail(i64 %x) {
+; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i64_fail(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i64 [[X:%.*]], -2
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i64
+; CHECK-NEXT:    [[C:%.*]] = lshr i64 [[X]], 62
+; CHECK-NEXT:    [[D:%.*]] = and i64 [[C]], [[B]]
+; CHECK-NEXT:    ret i64 [[D]]
+;
+  %A = icmp sge i64 %x, -1
+  %B = zext i1 %A to i64
+  %C = lshr i64 %x, 62
+  %D = and i64 %C, %B
+  ret i64 %D
+}
+
+define <2 x i32> @icmp_slt_0_and_icmp_sge_neg1_i32x2(<2 x i32> %x) {
+; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i32x2(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
+; CHECK-NEXT:    [[B:%.*]] = zext <2 x i1> [[A]] to <2 x i32>
+; CHECK-NEXT:    [[C:%.*]] = lshr <2 x i32> [[X]], <i32 31, i32 31>
+; CHECK-NEXT:    [[D:%.*]] = and <2 x i32> [[C]], [[B]]
+; CHECK-NEXT:    ret <2 x i32> [[D]]
+;
+  %A = icmp sge <2 x i32> %x, <i32 -1, i32 -1>
+  %B = zext <2 x i1> %A to <2 x i32>
+  %C = lshr <2 x i32> %x, <i32 31, i32 31>
+  %D = and <2 x i32> %C, %B
+  ret <2 x i32> %D
+}
+
+define <2 x i32> @icmp_slt_0_and_icmp_sge_neg2_i32x2(<2 x i32> %x) {
+; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i32x2(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 -3, i32 -3>
+; CHECK-NEXT:    [[B:%.*]] = zext <2 x i1> [[A]] to <2 x i32>
+; CHECK-NEXT:    [[C:%.*]] = lshr <2 x i32> [[X]], <i32 31, i32 31>
+; CHECK-NEXT:    [[D:%.*]] = and <2 x i32> [[C]], [[B]]
+; CHECK-NEXT:    ret <2 x i32> [[D]]
+;
+  %A = icmp sge <2 x i32> %x, <i32 -2, i32 -2>
+  %B = zext <2 x i1> %A to <2 x i32>
+  %C = lshr <2 x i32> %x, <i32 31, i32 31>
+  %D = and <2 x i32> %C, %B
+  ret <2 x i32> %D
+}
+
+
+define i32 @icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32(i32 %x, i32 %y) {
+; CHECK-LABEL: @icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -1
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[Y:%.*]], 31
+; CHECK-NEXT:    [[D:%.*]] = xor i32 [[C]], [[B]]
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp sgt i32 %x, -1
+  %B = zext i1 %A to i32
+  %C = lshr i32 %y, 31
+  %D = xor i32 %C, %B
+  ret i32 %D
+}
+
+define i32 @icmp_slt_0_xor_icmp_sgt_neg2_i32(i32 %x) {
+; CHECK-LABEL: @icmp_slt_0_xor_icmp_sgt_neg2_i32(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -2
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
+; CHECK-NEXT:    [[D:%.*]] = xor i32 [[C]], [[B]]
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp sgt i32 %x, -2
+  %B = zext i1 %A to i32
+  %C = lshr i32 %x, 31
+  %D = xor i32 %C, %B
+  ret i32 %D
+}
+
+define i32 @icmp_slt_0_and_icmp_sge_neg1_i32_multiuse0(i32 %x) {
+; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i32_multiuse0(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -3
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
+; CHECK-NEXT:    [[D:%.*]] = and i32 [[C]], [[B]]
+; CHECK-NEXT:    call void @use(i1 [[A]])
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp sge i32 %x, -2
+  %B = zext i1 %A to i32
+  %C = lshr i32 %x, 31
+  %D = and i32 %C, %B
+  call void @use(i1 %A)
+  ret i32 %D
+}
+
+define i32 @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse1(i32 %x) {
+; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse1(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -3
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
+; CHECK-NEXT:    [[D:%.*]] = and i32 [[C]], [[B]]
+; CHECK-NEXT:    call void @use32(i32 [[B]])
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp sge i32 %x, -2
+  %B = zext i1 %A to i32
+  %C = lshr i32 %x, 31
+  %D = and i32 %C, %B
+  call void @use32(i32 %B)
+  ret i32 %D
+}
+
+define i32 @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse2(i32 %x) {
+; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse2(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -3
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
+; CHECK-NEXT:    [[D:%.*]] = and i32 [[C]], [[B]]
+; CHECK-NEXT:    call void @use32(i32 [[C]])
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp sge i32 %x, -2
+  %B = zext i1 %A to i32
+  %C = lshr i32 %x, 31
+  %D = and i32 %C, %B
+  call void @use32(i32 %C)
+  ret i32 %D
+}
+
+define i32 @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse_fail0(i32 %x) {
+; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse_fail0(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -3
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
+; CHECK-NEXT:    [[D:%.*]] = and i32 [[C]], [[B]]
+; CHECK-NEXT:    call void @use32(i32 [[B]])
+; CHECK-NEXT:    call void @use32(i32 [[C]])
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp sge i32 %x, -2
+  %B = zext i1 %A to i32
+  %C = lshr i32 %x, 31
+  %D = and i32 %C, %B
+  call void @use32(i32 %B)
+  call void @use32(i32 %C)
+  ret i32 %D
+}
+
+define i32 @icmp_slt_0_or_icmp_eq_100_i32_multiuse_fail1(i32 %x) {
+; CHECK-LABEL: @icmp_slt_0_or_icmp_eq_100_i32_multiuse_fail1(
+; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 100
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
+; CHECK-NEXT:    [[D:%.*]] = or i32 [[C]], [[B]]
+; CHECK-NEXT:    call void @use32(i32 [[C]])
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp eq i32 %x, 100
+  %B = zext i1 %A to i32
+  %C = lshr i32 %x, 31
+  %D = or i32 %C, %B
+  call void @use32(i32 %C)
+  ret i32 %D
+}
+
+define i32 @icmp_x_slt_0_and_icmp_y_ne_neg2_i32_multiuse_fail2(i32 %x, i32 %y) {
+; CHECK-LABEL: @icmp_x_slt_0_and_icmp_y_ne_neg2_i32_multiuse_fail2(
+; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], -2
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[Y:%.*]], 31
+; CHECK-NEXT:    [[D:%.*]] = and i32 [[C]], [[B]]
+; CHECK-NEXT:    call void @use32(i32 [[C]])
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp ne i32 %x, -2
+  %B = zext i1 %A to i32
+  %C = lshr i32 %y, 31
+  %D = and i32 %C, %B
+  call void @use32(i32 %C)
+  ret i32 %D
+}
+
+define i32 @icmp_slt_0_or_icmp_eq_100_i32_multiuse_fail3(i32 %x) {
+; CHECK-LABEL: @icmp_slt_0_or_icmp_eq_100_i32_multiuse_fail3(
+; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 100
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
+; CHECK-NEXT:    [[D:%.*]] = or i32 [[C]], [[B]]
+; CHECK-NEXT:    call void @use32(i32 [[B]])
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp eq i32 %x, 100
+  %B = zext i1 %A to i32
+  %C = lshr i32 %x, 31
+  %D = or i32 %C, %B
+  call void @use32(i32 %B)
+  ret i32 %D
+}
+
+define i32 @icmp_slt_0_or_icmp_eq_100_i32_fail(i32 %x) {
+; CHECK-LABEL: @icmp_slt_0_or_icmp_eq_100_i32_fail(
+; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 100
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
+; CHECK-NEXT:    [[D:%.*]] = or i32 [[C]], [[B]]
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp eq i32 %x, 100
+  %B = zext i1 %A to i32
+  %C = lshr i32 %x, 31
+  %D = or i32 %C, %B
+  ret i32 %D
+}
+
+define i32 @icmp_slt_0_and_icmp_ne_neg2_i32_fail(i32 %x) {
+; CHECK-LABEL: @icmp_slt_0_and_icmp_ne_neg2_i32_fail(
+; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], -2
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
+; CHECK-NEXT:    [[D:%.*]] = and i32 [[C]], [[B]]
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp ne i32 %x, -2
+  %B = zext i1 %A to i32
+  %C = lshr i32 %x, 31
+  %D = and i32 %C, %B
+  ret i32 %D
+}
+
+define i32 @icmp_x_slt_0_and_icmp_y_ne_neg2_i32_fail(i32 %x, i32 %y) {
+; CHECK-LABEL: @icmp_x_slt_0_and_icmp_y_ne_neg2_i32_fail(
+; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], -2
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[Y:%.*]], 31
+; CHECK-NEXT:    [[D:%.*]] = and i32 [[C]], [[B]]
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp ne i32 %x, -2
+  %B = zext i1 %A to i32
+  %C = lshr i32 %y, 31
+  %D = and i32 %C, %B
+  ret i32 %D
+}
+
+define i32 @icmp_x_slt_0_and_icmp_y_sgt_neg1_i32_fail(i32 %x, i32 %y) {
+; CHECK-LABEL: @icmp_x_slt_0_and_icmp_y_sgt_neg1_i32_fail(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -1
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[Y:%.*]], 31
+; CHECK-NEXT:    [[D:%.*]] = and i32 [[C]], [[B]]
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp sgt i32 %x, -1
+  %B = zext i1 %A to i32
+  %C = lshr i32 %y, 31
+  %D = and i32 %C, %B
+  ret i32 %D
+}
+
+define i32 @icmp_slt_0_xor_icmp_sge_neg2_i32_fail(i32 %x) {
+; CHECK-LABEL: @icmp_slt_0_xor_icmp_sge_neg2_i32_fail(
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -3
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
+; CHECK-NEXT:    [[D:%.*]] = xor i32 [[C]], [[B]]
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %A = icmp sge i32 %x, -2
+  %B = zext i1 %A to i32
+  %C = lshr i32 %x, 31
+  %D = xor i32 %C, %B
+  ret i32 %D
+}
+
+define i32 @icmp_slt_0_or_icmp_add_1_sge_100_i32_fail(i32 %x) {
+; CHECK-LABEL: @icmp_slt_0_or_icmp_add_1_sge_100_i32_fail(
+; CHECK-NEXT:    [[X1:%.*]] = add i32 [[X:%.*]], 1
+; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X1]], 99
+; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
+; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
+; CHECK-NEXT:    [[D:%.*]] = or i32 [[C]], [[B]]
+; CHECK-NEXT:    ret i32 [[D]]
+;
+  %X1 = add i32 %x, 1
+  %A = icmp sge i32 %X1, 100
+  %B = zext i1 %A to i32
+  %C = lshr i32 %x, 31
+  %D = or i32 %C, %B
+  ret i32 %D
+}


        


More information about the llvm-commits mailing list