[InstCombine] move/add tests for icmp with mul operands; NFC
authorSanjay Patel <spatel@rotateright.com>
Mon, 7 Sep 2020 15:40:59 +0000 (11:40 -0400)
committerSanjay Patel <spatel@rotateright.com>
Mon, 7 Sep 2020 16:40:37 +0000 (12:40 -0400)
llvm/test/Transforms/InstCombine/icmp-mul.ll
llvm/test/Transforms/InstCombine/icmp.ll

index 8e7d905..7191500 100644 (file)
@@ -365,3 +365,314 @@ define i1 @ne_rem_zero_nonuw(i8 %x) {
   %b = icmp ne i8 %a, 30
   ret i1 %b
 }
+
+define i1 @mul_constant_eq(i32 %x, i32 %y) {
+; CHECK-LABEL: @mul_constant_eq(
+; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul i32 %x, 5
+  %B = mul i32 %y, 5
+  %C = icmp eq i32 %A, %B
+  ret i1 %C
+}
+
+define <2 x i1> @mul_constant_ne_splat(<2 x i32> %x, <2 x i32> %y) {
+; CHECK-LABEL: @mul_constant_ne_splat(
+; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    ret <2 x i1> [[C]]
+;
+  %A = mul <2 x i32> %x, <i32 5, i32 5>
+  %B = mul <2 x i32> %y, <i32 5, i32 5>
+  %C = icmp ne <2 x i32> %A, %B
+  ret <2 x i1> %C
+}
+
+define i1 @mul_constant_ne_extra_use1(i8 %x, i8 %y) {
+; CHECK-LABEL: @mul_constant_ne_extra_use1(
+; CHECK-NEXT:    [[A:%.*]] = mul i8 [[X:%.*]], 5
+; CHECK-NEXT:    call void @use(i8 [[A]])
+; CHECK-NEXT:    [[B:%.*]] = mul i8 [[Y:%.*]], 5
+; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul i8 %x, 5
+  call void @use(i8 %A)
+  %B = mul i8 %y, 5
+  %C = icmp ne i8 %A, %B
+  ret i1 %C
+}
+
+define i1 @mul_constant_eq_extra_use2(i8 %x, i8 %y) {
+; CHECK-LABEL: @mul_constant_eq_extra_use2(
+; CHECK-NEXT:    [[A:%.*]] = mul i8 [[X:%.*]], 5
+; CHECK-NEXT:    [[B:%.*]] = mul i8 [[Y:%.*]], 5
+; CHECK-NEXT:    call void @use(i8 [[B]])
+; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul i8 %x, 5
+  %B = mul i8 %y, 5
+  call void @use(i8 %B)
+  %C = icmp eq i8 %A, %B
+  ret i1 %C
+}
+
+define i1 @mul_constant_ne_extra_use3(i8 %x, i8 %y) {
+; CHECK-LABEL: @mul_constant_ne_extra_use3(
+; CHECK-NEXT:    [[A:%.*]] = mul i8 [[X:%.*]], 5
+; CHECK-NEXT:    call void @use(i8 [[A]])
+; CHECK-NEXT:    [[B:%.*]] = mul i8 [[Y:%.*]], 5
+; CHECK-NEXT:    call void @use(i8 [[B]])
+; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul i8 %x, 5
+  call void @use(i8 %A)
+  %B = mul i8 %y, 5
+  call void @use(i8 %B)
+  %C = icmp ne i8 %A, %B
+  ret i1 %C
+}
+
+define i1 @mul_constant_eq_nsw(i32 %x, i32 %y) {
+; CHECK-LABEL: @mul_constant_eq_nsw(
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 2147483647
+; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul nsw i32 %x, 6
+  %B = mul nsw i32 %y, 6
+  %C = icmp eq i32 %A, %B
+  ret i1 %C
+}
+
+define <2 x i1> @mul_constant_ne_nsw_splat(<2 x i32> %x, <2 x i32> %y) {
+; CHECK-LABEL: @mul_constant_ne_nsw_splat(
+; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 1073741823, i32 1073741823>
+; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    ret <2 x i1> [[C]]
+;
+  %A = mul nsw <2 x i32> %x, <i32 12, i32 12>
+  %B = mul nsw <2 x i32> %y, <i32 12, i32 12>
+  %C = icmp ne <2 x i32> %A, %B
+  ret <2 x i1> %C
+}
+
+define i1 @mul_constant_ne_nsw_extra_use1(i8 %x, i8 %y) {
+; CHECK-LABEL: @mul_constant_ne_nsw_extra_use1(
+; CHECK-NEXT:    [[A:%.*]] = mul nsw i8 [[X:%.*]], 74
+; CHECK-NEXT:    call void @use(i8 [[A]])
+; CHECK-NEXT:    [[B:%.*]] = mul nsw i8 [[Y:%.*]], 74
+; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul nsw i8 %x, 74
+  call void @use(i8 %A)
+  %B = mul nsw i8 %y, 74
+  %C = icmp ne i8 %A, %B
+  ret i1 %C
+}
+
+define i1 @mul_constant_eq_nsw_extra_use2(i8 %x, i8 %y) {
+; CHECK-LABEL: @mul_constant_eq_nsw_extra_use2(
+; CHECK-NEXT:    [[A:%.*]] = mul nsw i8 [[X:%.*]], 20
+; CHECK-NEXT:    [[B:%.*]] = mul nsw i8 [[Y:%.*]], 20
+; CHECK-NEXT:    call void @use(i8 [[B]])
+; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul nsw i8 %x, 20
+  %B = mul nsw i8 %y, 20
+  call void @use(i8 %B)
+  %C = icmp eq i8 %A, %B
+  ret i1 %C
+}
+
+define i1 @mul_constant_ne_nsw_extra_use3(i8 %x, i8 %y) {
+; CHECK-LABEL: @mul_constant_ne_nsw_extra_use3(
+; CHECK-NEXT:    [[A:%.*]] = mul nsw i8 [[X:%.*]], 24
+; CHECK-NEXT:    call void @use(i8 [[A]])
+; CHECK-NEXT:    [[B:%.*]] = mul nsw i8 [[Y:%.*]], 24
+; CHECK-NEXT:    call void @use(i8 [[B]])
+; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul nsw i8 %x, 24
+  call void @use(i8 %A)
+  %B = mul nsw i8 %y, 24
+  call void @use(i8 %B)
+  %C = icmp ne i8 %A, %B
+  ret i1 %C
+}
+
+define i1 @mul_constant_nuw_eq(i32 %x, i32 %y) {
+; CHECK-LABEL: @mul_constant_nuw_eq(
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 2147483647
+; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul nuw i32 %x, 22
+  %B = mul nuw i32 %y, 22
+  %C = icmp eq i32 %A, %B
+  ret i1 %C
+}
+
+define <2 x i1> @mul_constant_ne_nuw_splat(<2 x i32> %x, <2 x i32> %y) {
+; CHECK-LABEL: @mul_constant_ne_nuw_splat(
+; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 2147483647, i32 2147483647>
+; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    ret <2 x i1> [[C]]
+;
+  %A = mul nuw <2 x i32> %x, <i32 10, i32 10>
+  %B = mul nuw <2 x i32> %y, <i32 10, i32 10>
+  %C = icmp ne <2 x i32> %A, %B
+  ret <2 x i1> %C
+}
+
+define i1 @mul_constant_ne_nuw_extra_use1(i8 %x, i8 %y) {
+; CHECK-LABEL: @mul_constant_ne_nuw_extra_use1(
+; CHECK-NEXT:    [[A:%.*]] = mul nuw i8 [[X:%.*]], 6
+; CHECK-NEXT:    call void @use(i8 [[A]])
+; CHECK-NEXT:    [[B:%.*]] = mul nuw i8 [[Y:%.*]], 6
+; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul nuw i8 %x, 6
+  call void @use(i8 %A)
+  %B = mul nuw i8 %y, 6
+  %C = icmp ne i8 %A, %B
+  ret i1 %C
+}
+
+define i1 @mul_constant_eq_nuw_extra_use2(i8 %x, i8 %y) {
+; CHECK-LABEL: @mul_constant_eq_nuw_extra_use2(
+; CHECK-NEXT:    [[A:%.*]] = mul nuw i8 [[X:%.*]], 36
+; CHECK-NEXT:    [[B:%.*]] = mul nuw i8 [[Y:%.*]], 36
+; CHECK-NEXT:    call void @use(i8 [[B]])
+; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul nuw i8 %x, 36
+  %B = mul nuw i8 %y, 36
+  call void @use(i8 %B)
+  %C = icmp eq i8 %A, %B
+  ret i1 %C
+}
+
+define i1 @mul_constant_ne_nuw_extra_use3(i8 %x, i8 %y) {
+; CHECK-LABEL: @mul_constant_ne_nuw_extra_use3(
+; CHECK-NEXT:    [[A:%.*]] = mul nuw i8 [[X:%.*]], 38
+; CHECK-NEXT:    call void @use(i8 [[A]])
+; CHECK-NEXT:    [[B:%.*]] = mul nuw i8 [[Y:%.*]], 38
+; CHECK-NEXT:    call void @use(i8 [[B]])
+; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul nuw i8 %x, 38
+  call void @use(i8 %A)
+  %B = mul nuw i8 %y, 38
+  call void @use(i8 %B)
+  %C = icmp ne i8 %A, %B
+  ret i1 %C
+}
+
+define i1 @mul_constant_ult(i32 %x, i32 %y) {
+; CHECK-LABEL: @mul_constant_ult(
+; CHECK-NEXT:    [[A:%.*]] = mul i32 [[X:%.*]], 47
+; CHECK-NEXT:    [[B:%.*]] = mul i32 [[Y:%.*]], 47
+; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul i32 %x, 47
+  %B = mul i32 %y, 47
+  %C = icmp ult i32 %A, %B
+  ret i1 %C
+}
+
+define i1 @mul_constant_nuw_sgt(i32 %x, i32 %y) {
+; CHECK-LABEL: @mul_constant_nuw_sgt(
+; CHECK-NEXT:    [[A:%.*]] = mul nuw i32 [[X:%.*]], 46
+; CHECK-NEXT:    [[B:%.*]] = mul nuw i32 [[Y:%.*]], 46
+; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul nuw i32 %x, 46
+  %B = mul nuw i32 %y, 46
+  %C = icmp sgt i32 %A, %B
+  ret i1 %C
+}
+
+define i1 @mul_mismatch_constant_nuw_eq(i32 %x, i32 %y) {
+; CHECK-LABEL: @mul_mismatch_constant_nuw_eq(
+; CHECK-NEXT:    [[A:%.*]] = mul nuw i32 [[X:%.*]], 46
+; CHECK-NEXT:    [[B:%.*]] = mul nuw i32 [[Y:%.*]], 44
+; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[A]], [[B]]
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul nuw i32 %x, 46
+  %B = mul nuw i32 %y, 44
+  %C = icmp eq i32 %A, %B
+  ret i1 %C
+}
+
+; If the multiply constant has any trailing zero bits but could overflow,
+; we get something completely different.
+; We mask off the high bits of each input and then convert:
+; (X&Z) == (Y&Z) -> (X^Y) & Z == 0
+
+define i1 @mul_constant_partial_nuw_eq(i32 %x, i32 %y) {
+; CHECK-LABEL: @mul_constant_partial_nuw_eq(
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 1073741823
+; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul i32 %x, 44
+  %B = mul nuw i32 %y, 44
+  %C = icmp eq i32 %A, %B
+  ret i1 %C
+}
+
+define i1 @mul_constant_mismatch_wrap_eq(i32 %x, i32 %y) {
+; CHECK-LABEL: @mul_constant_mismatch_wrap_eq(
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 2147483647
+; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul nsw i32 %x, 54
+  %B = mul nuw i32 %y, 54
+  %C = icmp eq i32 %A, %B
+  ret i1 %C
+}
+
+define i1 @eq_mul_constants_with_tz(i32 %x, i32 %y) {
+; CHECK-LABEL: @eq_mul_constants_with_tz(
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 1073741823
+; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[TMP2]], 0
+; CHECK-NEXT:    ret i1 [[C]]
+;
+  %A = mul i32 %x, 12
+  %B = mul i32 %y, 12
+  %C = icmp ne i32 %A, %B
+  ret i1 %C
+}
+
+define <2 x i1> @eq_mul_constants_with_tz_splat(<2 x i32> %x, <2 x i32> %y) {
+; CHECK-LABEL: @eq_mul_constants_with_tz_splat(
+; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 1073741823, i32 1073741823>
+; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i32> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    ret <2 x i1> [[C]]
+;
+  %A = mul <2 x i32> %x, <i32 12, i32 12>
+  %B = mul <2 x i32> %y, <i32 12, i32 12>
+  %C = icmp eq <2 x i32> %A, %B
+  ret <2 x i1> %C
+}
index a9bda13..6835181 100644 (file)
@@ -3397,58 +3397,6 @@ define i1 @eq_add_constants(i32 %x, i32 %y) {
   ret i1 %C
 }
 
-define i1 @eq_mul_constants(i32 %x, i32 %y) {
-; CHECK-LABEL: @eq_mul_constants(
-; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    ret i1 [[C]]
-;
-  %A = mul i32 %x, 5
-  %B = mul i32 %y, 5
-  %C = icmp eq i32 %A, %B
-  ret i1 %C
-}
-
-define <2 x i1> @eq_mul_constants_splat(<2 x i32> %x, <2 x i32> %y) {
-; CHECK-LABEL: @eq_mul_constants_splat(
-; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i32> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    ret <2 x i1> [[C]]
-;
-  %A = mul <2 x i32> %x, <i32 5, i32 5>
-  %B = mul <2 x i32> %y, <i32 5, i32 5>
-  %C = icmp ne <2 x i32> %A, %B
-  ret <2 x i1> %C
-}
-
-; If the multiply constant has any trailing zero bits, we get something completely different.
-; We mask off the high bits of each input and then convert:
-; (X&Z) == (Y&Z) -> (X^Y) & Z == 0
-
-define i1 @eq_mul_constants_with_tz(i32 %x, i32 %y) {
-; CHECK-LABEL: @eq_mul_constants_with_tz(
-; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 1073741823
-; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[TMP2]], 0
-; CHECK-NEXT:    ret i1 [[C]]
-;
-  %A = mul i32 %x, 12
-  %B = mul i32 %y, 12
-  %C = icmp ne i32 %A, %B
-  ret i1 %C
-}
-
-define <2 x i1> @eq_mul_constants_with_tz_splat(<2 x i32> %x, <2 x i32> %y) {
-; CHECK-LABEL: @eq_mul_constants_with_tz_splat(
-; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 1073741823, i32 1073741823>
-; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i32> [[TMP2]], zeroinitializer
-; CHECK-NEXT:    ret <2 x i1> [[C]]
-;
-  %A = mul <2 x i32> %x, <i32 12, i32 12>
-  %B = mul <2 x i32> %y, <i32 12, i32 12>
-  %C = icmp eq <2 x i32> %A, %B
-  ret <2 x i1> %C
-}
-
 declare i32 @llvm.bswap.i32(i32)
 
 define i1 @bswap_ne(i32 %x, i32 %y) {